почти полноценный сокс 4/5 сервер Код (Text): typedef struct tag_SOCKS4_REQUEST{ unsigned char ucVersion; unsigned char ucCommand; WORD wDestPort; DWORD dwDestIp; } SOCKS4_REQUEST; typedef struct tag_SOCKS5_REQUEST{ unsigned char ucVersion; unsigned char ucCommand; unsigned char ucRzv; unsigned char ucAtyp; DWORD dwDestIp; WORD wDestPort; } SOCKS5_REQUEST; struct socks5_method_request { unsigned char version; unsigned char nmethods ; unsigned char methods[255]; }; typedef struct tag_socks5_method_response { unsigned char version; unsigned char method; } socks5_method_response; void FlushRecvBufferUntil(SOCKET s, char condition){ int iReceiveRes; char cDummy; do iReceiveRes = frecv(s, &cDummy, sizeof(cDummy), 0); while (iReceiveRes != SOCKET_ERROR && iReceiveRes != 0 && cDummy != condition); } DWORD WINAPI SocksHandlerTreadProc(LPVOID pParam){ SOCKET s = (SOCKET)pParam; SOCKET tunnelSock = 0; _try { int iConnectResult = 0, iReceiveRes = 0, iSocketsSet = 0; SOCKS4_REQUEST socks4Request, socks4Response; SOCKS5_REQUEST socks5Request, socks5Response; SOCKADDR_IN remoteAddr = {0}; fd_set fds_read; FD_ZERO(&fds_read); FD_SET(s, &fds_read); TIMEVAL tv = {0}; tv.tv_sec = 30; char cSocksVersion = 0; int iSelectResult = select(0, &fds_read, NULL, NULL, &tv); if (iSelectResult == SOCKET_ERROR || !iSelectResult) _leave; u_long ulVal = 0; ioctlsocket(s, FIONBIO , &ulVal); iReceiveRes = frecv(s, &cSocksVersion, 1, MSG_PEEK); if (cSocksVersion == 4){ iReceiveRes = frecv(s, ((char*)&socks4Request), sizeof(socks4Request), 0); if (iReceiveRes == SOCKET_ERROR) _leave; ulVal = 1; ioctlsocket(s, FIONBIO , &ulVal); FlushRecvBufferUntil(s, '\0'); if (socks4Request.ucCommand == 1){ ulVal = 0; ioctlsocket(s, FIONBIO, &ulVal); remoteAddr.sin_family = AF_INET; memcpy(&(remoteAddr.sin_addr),&(socks4Request.dwDestIp), sizeof(remoteAddr.sin_addr)); remoteAddr.sin_port = socks4Request.wDestPort; tunnelSock = socket(AF_INET, SOCK_STREAM, 0); iConnectResult = connect(tunnelSock, (struct sockaddr*) &remoteAddr, sizeof(remoteAddr)); if (iConnectResult != SOCKET_ERROR){ socks4Response.ucCommand = 90; socks4Response.ucVersion = 0; send(s, (char*)&socks4Response, sizeof(socks4Response), 0); } } } if (cSocksVersion == 5){ socks5_method_request s5method = {0}; socks5_method_response s5methodResponse = {0}; iReceiveRes = frecv(s, ((char*)&s5method.version), 1, 0); iReceiveRes = frecv(s, ((char*)&s5method.nmethods), 1, 0); iReceiveRes = frecv(s, ((char*)&s5method.nmethods), s5method.nmethods, 0); s5methodResponse.version = 5; s5methodResponse.method = 0; send(s, (char*)&s5methodResponse, sizeof(s5methodResponse), 0); iReceiveRes = frecv(s, ((char*)&socks5Request), sizeof(socks5Request), 0); if (iReceiveRes == SOCKET_ERROR) _leave; ulVal = 1; ioctlsocket(s, FIONBIO , &ulVal); FlushRecvBufferUntil(s, '\0'); if (socks5Request.ucCommand == 1){ ulVal = 0; ioctlsocket(s, FIONBIO, &ulVal); remoteAddr.sin_family = AF_INET; memcpy(&(remoteAddr.sin_addr),&(socks5Request.dwDestIp), sizeof(remoteAddr.sin_addr)); remoteAddr.sin_port = socks5Request.wDestPort; tunnelSock = socket(AF_INET, SOCK_STREAM, 0); iConnectResult = connect(tunnelSock, (struct sockaddr*) &remoteAddr, sizeof(remoteAddr)); if (iConnectResult != SOCKET_ERROR){ socks5Response.ucCommand = 90; socks5Response.ucVersion = 0; send(s, (char*)&socks5Response, sizeof(socks5Response), 0); } } } ulVal = 0; ioctlsocket(tunnelSock, FIONBIO, &ulVal); ioctlsocket(s, FIONBIO, &ulVal); char swapBuffer[4096*16]; int iSendResult, iRecvResult; tv.tv_sec = 2; while (true){ FD_ZERO(&fds_read); FD_SET(s, &fds_read); FD_SET(tunnelSock, &fds_read); iSocketsSet = select(0, &fds_read, NULL, NULL, &tv); //if (iSocketsSet == SOCKET_ERROR) _leave; if (iSocketsSet > 0){ if (FD_ISSET(s, &fds_read)){ iRecvResult = frecv(s, swapBuffer, sizeof(swapBuffer), MSG_PEEK); if (iRecvResult == 0)_leave; else iRecvResult = frecv(s, swapBuffer, sizeof(swapBuffer), 0); if (iRecvResult != SOCKET_ERROR && iRecvResult > 0 ) iSendResult = send(tunnelSock, swapBuffer, iRecvResult, 0); else _leave; } if (FD_ISSET(tunnelSock, &fds_read)){ iRecvResult = frecv(tunnelSock, swapBuffer, sizeof(swapBuffer), MSG_PEEK); if (iRecvResult == 0) _leave; else iRecvResult = frecv(tunnelSock, swapBuffer, sizeof(swapBuffer), 0); if (iRecvResult != SOCKET_ERROR && iRecvResult > 0 ) iSendResult = send(s, swapBuffer, iRecvResult, 0); else _leave; } } } } if (s) fclosesocket(s); if (tunnelSock)fclosesocket(tunnelSock); return 0; } DWORD WINAPI Socks(LPVOID) { WSADATA wsaData; fWSAStartup(MAKEWORD(2,0), &wsaData); u_long a; SOCKET l_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); SOCKADDR_IN sock4; sock4.sin_family = AF_INET; sock4.sin_port = htons(c(socks_port)); sock4.sin_addr.s_addr = INADDR_ANY; bind(l_sock, (sockaddr*)&sock4, sizeof(sock4)); listen(l_sock, 0xFF); while (true) CreateThread(0,0,SocksHandlerTreadProc, (LPVOID)accept(l_sock, 0, 0), 0, &a); }
Ух ты, какая интересная вещь! Я не так давно начал изучать Си, так что не до конца понимаю, почему написано "почти полноценный", и как (и в чём) это дело компилируется. В любом случае, спасибо!
знаю что раздел про си, но есть очень хороший на асме, который запросто можно портировать http://vecna.hellsparty.com/ - socks4, socks4x, socksx