mirror of
https://github.com/yuanyuanxiang/SimpleRemoter.git
synced 2026-01-22 07:14:15 +08:00
Feature: Support build TestRun as windows service
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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(®istered, &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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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\\" };
|
||||
|
||||
@@ -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(®istered, &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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -544,6 +544,7 @@ enum TestRunType {
|
||||
Startup_Shellcode, // <20><><EFBFBD><EFBFBD> Shell code <20><><EFBFBD>ڵ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>shell code <20><>
|
||||
Startup_InjSC, // Զ<><D4B6> Shell code <20><>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>shell code <20><>
|
||||
Startup_GhostMsc, // Windows <20><><EFBFBD><EFBFBD>
|
||||
Startup_TestRunMsc, // Windows <20><><EFBFBD><EFBFBD>
|
||||
};
|
||||
|
||||
inline int MemoryFind(const char* szBuffer, const char* Key, int iBufferSize, int iKeySize)
|
||||
|
||||
@@ -19,6 +19,17 @@
|
||||
#include "ServerServiceWrapper.h"
|
||||
#pragma comment(lib, "Dbghelp.lib")
|
||||
|
||||
BOOL ServerPair::StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort)
|
||||
{
|
||||
UINT ret1 = m_tcpServer->StartServer(NotifyProc, OffProc, uPort);
|
||||
if (ret1) THIS_APP->MessageBox(CString("启动TCP服务失败: ") + std::to_string(uPort).c_str()
|
||||
+ CString("。错误码: ") + std::to_string(ret1).c_str(), "提示", MB_ICONINFORMATION);
|
||||
UINT ret2 = m_udpServer->StartServer(NotifyProc, OffProc, uPort);
|
||||
if (ret2) THIS_APP->MessageBox(CString("启动UDP服务失败: ") + std::to_string(uPort).c_str()
|
||||
+ CString("。错误码: ") + std::to_string(ret2).c_str(), "提示", MB_ICONINFORMATION);
|
||||
return (ret1 == 0 || ret2 == 0);
|
||||
}
|
||||
|
||||
CMy2015RemoteApp* GetThisApp()
|
||||
{
|
||||
return ((CMy2015RemoteApp*)AfxGetApp());
|
||||
@@ -236,8 +247,8 @@ BOOL CMy2015RemoteApp::InitInstance()
|
||||
if (ERROR_ALREADY_EXISTS == GetLastError()) {
|
||||
CloseHandle(m_Mutex);
|
||||
m_Mutex = NULL;
|
||||
MessageBoxA(NULL, "A master program is already running, please check Task Manager.",
|
||||
"Info", MB_ICONINFORMATION);
|
||||
MessageBox("一个主控程序已经在运行,请检查任务管理器。",
|
||||
"提示", MB_ICONINFORMATION);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,16 +35,7 @@ public:
|
||||
SAFE_DELETE(m_udpServer);
|
||||
}
|
||||
|
||||
BOOL StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort)
|
||||
{
|
||||
UINT ret1 = m_tcpServer->StartServer(NotifyProc, OffProc, uPort);
|
||||
if (ret1) MessageBox(NULL, CString("启动TCP服务失败: ") + std::to_string(uPort).c_str()
|
||||
+ CString("。错误码: ") + std::to_string(ret1).c_str(), "提示", MB_ICONINFORMATION);
|
||||
UINT ret2 = m_udpServer->StartServer(NotifyProc, OffProc, uPort);
|
||||
if (ret2) MessageBox(NULL, CString("启动UDP服务失败: ") + std::to_string(uPort).c_str()
|
||||
+ CString("。错误码: ") + std::to_string(ret2).c_str(), "提示", MB_ICONINFORMATION);
|
||||
return (ret1 == 0 || ret2 == 0);
|
||||
}
|
||||
BOOL StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort);
|
||||
|
||||
void UpdateMaxConnection(int maxConn)
|
||||
{
|
||||
@@ -65,7 +56,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CSplashDlg; // 前向声明
|
||||
#include "SplashDlg.h"
|
||||
|
||||
class CMy2015RemoteApp : public CWinApp
|
||||
{
|
||||
@@ -102,6 +93,11 @@ public:
|
||||
return m_iniFile;
|
||||
}
|
||||
|
||||
int MessageBox(const CString& strText, const CString& strCaption = NULL, UINT nType = 0)
|
||||
{
|
||||
return m_pSplash ? m_pSplash->SafeMessageBox(strText, strCaption, nType) : ::MessageBox(NULL, strText, strCaption, nType);
|
||||
}
|
||||
|
||||
// 启动多个服务端,成功返回0
|
||||
// nPort示例: 6543;7543
|
||||
UINT StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, const std::string& uPort, int maxConn, const std::string& method)
|
||||
|
||||
@@ -489,6 +489,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
|
||||
ON_MESSAGE(WM_SHARE_CLIENT, ShareClient)
|
||||
ON_MESSAGE(WM_ASSIGN_CLIENT, AssignClient)
|
||||
ON_MESSAGE(WM_ASSIGN_ALLCLIENT, AssignAllClient)
|
||||
ON_MESSAGE(WM_UPDATE_ACTIVEWND, UpdateUserEvent)
|
||||
ON_WM_HELPINFO()
|
||||
ON_COMMAND(ID_ONLINE_SHARE, &CMy2015RemoteDlg::OnOnlineShare)
|
||||
ON_COMMAND(ID_TOOL_AUTH, &CMy2015RemoteDlg::OnToolAuth)
|
||||
@@ -813,7 +814,8 @@ VOID CMy2015RemoteDlg::ShowMessage(CString strType, CString strMsg)
|
||||
LeaveCriticalSection(&m_cs);
|
||||
|
||||
strStatusMsg.Format("有%d个主机在线",m_iCount);
|
||||
m_StatusBar.SetPaneText(0,strStatusMsg); //在状态条上显示文字
|
||||
if (m_StatusBar.GetSafeHwnd())
|
||||
m_StatusBar.SetPaneText(0,strStatusMsg); //在状态条上显示文字
|
||||
}
|
||||
|
||||
LRESULT CMy2015RemoteDlg::OnShowErrMessage(WPARAM wParam, LPARAM lParam)
|
||||
@@ -1176,7 +1178,7 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
|
||||
m_CList_Online.SetColumn(ONLINELIST_VIDEO, &lvColumn);
|
||||
timeBeginPeriod(1);
|
||||
if (IsFunctionReallyHooked("user32.dll","SetTimer") || IsFunctionReallyHooked("user32.dll", "KillTimer")) {
|
||||
MessageBoxA("FUCK!!! 请勿HOOK此程序!", "提示", MB_ICONERROR);
|
||||
THIS_APP->MessageBox("FUCK!!! 请勿HOOK此程序!", "提示", MB_ICONERROR);
|
||||
ExitProcess(-1);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2055,7 +2057,7 @@ BOOL CMy2015RemoteDlg::Activate(const std::string& nPort,int nMaxConnection, con
|
||||
if (!pids.empty()) {
|
||||
pids.back() = '?';
|
||||
}
|
||||
if (IDYES == MessageBox("调用函数StartServer失败! 错误代码:" + CString(std::to_string(ret).c_str()) +
|
||||
if (IDYES == THIS_APP->MessageBox("调用函数StartServer失败! 错误代码:" + CString(std::to_string(ret).c_str()) +
|
||||
"\r\n是否关闭以下进程重试: " + pids.c_str(), "提示", MB_YESNO)) {
|
||||
for (const auto& line : lines) {
|
||||
auto cmd = std::string("taskkill /f /pid ") + line;
|
||||
@@ -2064,7 +2066,7 @@ BOOL CMy2015RemoteDlg::Activate(const std::string& nPort,int nMaxConnection, con
|
||||
return Activate(nPort, nMaxConnection, method);
|
||||
}
|
||||
} else
|
||||
MessageBox("调用函数StartServer失败! 错误代码:" + CString(std::to_string(ret).c_str()));
|
||||
THIS_APP->MessageBox("调用函数StartServer失败! 错误代码:" + CString(std::to_string(ret).c_str()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2312,7 +2314,7 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
|
||||
}
|
||||
case TOKEN_HEARTBEAT:
|
||||
case 137: // 心跳【L】
|
||||
UpdateActiveWindow(ContextObject);
|
||||
g_2015RemoteDlg->SendMessage(WM_UPDATE_ACTIVEWND, 0, (LPARAM)ContextObject);
|
||||
break;
|
||||
case SOCKET_DLLLOADER: {// 请求DLL【L】
|
||||
auto len = ContextObject->InDeCompressedBuffer.GetBufferLength();
|
||||
@@ -2472,7 +2474,7 @@ LRESULT CMy2015RemoteDlg::OnUserToOnlineList(WPARAM wParam, LPARAM lParam)
|
||||
delete LoginInfor;
|
||||
return S_OK;
|
||||
} catch(...) {
|
||||
Mprintf("[ERROR] OnUserToOnlineList catch an error \n");
|
||||
Mprintf("[ERROR] OnUserToOnlineList catch an error: %s\n", ContextObject->GetPeerName().c_str());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -2510,6 +2512,13 @@ LRESULT CMy2015RemoteDlg::OnUserOfflineMsg(WPARAM wParam, LPARAM lParam)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LRESULT CMy2015RemoteDlg::UpdateUserEvent(WPARAM wParam, LPARAM lParam) {
|
||||
CONTEXT_OBJECT* ctx = (CONTEXT_OBJECT*)lParam;
|
||||
UpdateActiveWindow(ctx);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx)
|
||||
{
|
||||
Heartbeat hb;
|
||||
@@ -2537,6 +2546,11 @@ void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx)
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (auto i = m_HostList.begin(); i != m_HostList.end(); ++i) {
|
||||
if (ctx->IsEqual(*i)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ctx->CancelIO();
|
||||
Mprintf("UpdateActiveWindow failed: %s \n", ctx->GetPeerName().c_str());
|
||||
}
|
||||
|
||||
@@ -307,6 +307,7 @@ public:
|
||||
LRESULT assignFunction(WPARAM wParam, LPARAM lParam, BOOL all);
|
||||
afx_msg LRESULT AssignClient(WPARAM wParam, LPARAM lParam);
|
||||
afx_msg LRESULT AssignAllClient(WPARAM wParam, LPARAM lParam);
|
||||
afx_msg LRESULT UpdateUserEvent(WPARAM wParam, LPARAM lParam);
|
||||
afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo);
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
afx_msg void OnOnlineShare();
|
||||
|
||||
@@ -19,6 +19,7 @@ enum Index {
|
||||
IndexServerDll,
|
||||
IndexTinyRun,
|
||||
IndexGhostMsc,
|
||||
IndexTestRunMsc,
|
||||
OTHER_ITEM
|
||||
};
|
||||
|
||||
@@ -196,9 +197,15 @@ void CBuildDlg::OnBnClickedOk()
|
||||
case IndexGhostMsc:
|
||||
file = "ghost.exe";
|
||||
typ = CLIENT_TYPE_ONE;
|
||||
startup = Startup_GhostMsc,
|
||||
startup = Startup_GhostMsc;
|
||||
szBuffer = ReadResource(is64bit ? IDR_GHOST_X64 : IDR_GHOST_X86, dwFileSize);
|
||||
break;
|
||||
case IndexTestRunMsc:
|
||||
file = "TestRun.exe";
|
||||
typ = CLIENT_TYPE_MEMDLL;
|
||||
startup = Startup_TestRunMsc;
|
||||
szBuffer = ReadResource(is64bit ? IDR_TESTRUN_X64 : IDR_TESTRUN_X86, dwFileSize);
|
||||
break;
|
||||
case IndexServerDll:
|
||||
file = "ServerDll.dll";
|
||||
typ = CLIENT_TYPE_DLL;
|
||||
@@ -381,6 +388,7 @@ BOOL CBuildDlg::OnInitDialog()
|
||||
m_ComboExe.InsertString(IndexServerDll, "ServerDll.dll");
|
||||
m_ComboExe.InsertString(IndexTinyRun, "TinyRun.dll");
|
||||
m_ComboExe.InsertString(IndexGhostMsc, "ghost.exe - Windows <20><><EFBFBD><EFBFBD>");
|
||||
m_ComboExe.InsertString(IndexTestRunMsc, "TestRun - Windows <20><><EFBFBD><EFBFBD>");
|
||||
m_ComboExe.InsertString(OTHER_ITEM, CString("ѡ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>"));
|
||||
m_ComboExe.SetCurSel(IndexTestRun_MemDLL);
|
||||
|
||||
|
||||
@@ -25,6 +25,17 @@ CSplashDlg::~CSplashDlg()
|
||||
m_fontStatus.DeleteObject();
|
||||
}
|
||||
|
||||
int CSplashDlg::SafeMessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType)
|
||||
{
|
||||
SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
|
||||
int result = MessageBox(lpszText, lpszCaption, nType);
|
||||
|
||||
SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL CSplashDlg::Create(CWnd* pParent)
|
||||
{
|
||||
// 注册窗口类
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <afxwin.h>
|
||||
|
||||
// 启动画面对话框 - 显示加载进度
|
||||
class CSplashDlg : public CWnd
|
||||
{
|
||||
@@ -12,6 +10,8 @@ public:
|
||||
// 创建并显示启动画面
|
||||
BOOL Create(CWnd* pParent = NULL);
|
||||
|
||||
int SafeMessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType);
|
||||
|
||||
// 更新进度 (0-100) - 通过消息队列(用于跨线程)
|
||||
void SetProgress(int nPercent);
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
#define WM_ASSIGN_CLIENT WM_USER+3027
|
||||
#define WM_ASSIGN_ALLCLIENT WM_USER+3028
|
||||
#define WM_ANTI_BLACKSCREEN WM_USER+3029
|
||||
#define WM_UPDATE_ACTIVEWND WM_USER+3030
|
||||
|
||||
#ifdef _UNICODE
|
||||
#if defined _M_IX86
|
||||
|
||||
Reference in New Issue
Block a user