TcpIpdog.cpp
上传用户:kklily621
上传日期:2013-06-25
资源大小:252k
文件大小:14k
开发平台:

Visual C++

  1. /*=============================================================================================
  2. 文件: TcpIpDog.cpp
  3. 说明:
  4. ---------------------------------------------------
  5. Winsock 钩子,用来截获 Winsock 调用从而拦截
  6. TCP/IP封包,并做相应处理。
  7. ---------------------------------------------------
  8. 工程: Xfilter 个人防火墙
  9. 作者: 朱雁辉,朱雁冰
  10. 创建日期: 2001/08/21
  11. 网址: http://www.xfilt.com
  12. 电子邮件: xstudio@xfilt.com
  13. 版权所有 (c) 2001-2002 X 工作室
  14. 警告:
  15. ---------------------------------------------------
  16. 本电脑程序受著作权法的保护。未经授权,不能使用
  17. 和修改本软件全部或部分源代码。凡擅自复制、盗用或散
  18. 布此程序或部分程序或者有其它任何越权行为,将遭到民
  19. 事赔偿及刑事的处罚,并将依法以最高刑罚进行追诉。
  20. 凡通过合法途径购买本软件源代码的用户被默认授权
  21. 可以在自己的程序中使用本软件的部分代码,但作者不对
  22. 代码产生的任何后果负责。
  23. 使用了本软件代码的程序只能以可执行文件形式发布,
  24. 未经特别许可,不能将含有本软件源代码的源程序以任何
  25. 形式发布。
  26. ---------------------------------------------------
  27. */
  28. //=============================================================================================
  29. // include header file and global variables
  30. #include "stdafx.h"
  31. #include "TcpIpDog.h"
  32. #include "CheckAcl.h"
  33. #pragma data_seg(".inidata")
  34. int gAclChangeCount = INIT_ACL_CHANGE_COUNT;
  35. int m_iDllCount = 0;
  36. #pragma data_seg()
  37. #pragma bss_seg(".uinidata")
  38. QUERY_SESSION m_QuerySession[MAX_QUERY_SESSION];
  39. #pragma bss_seg()
  40. CCheckAcl m_CheckAcl;
  41. CRITICAL_SECTION gCriticalSection;
  42. WSPPROC_TABLE NextProcTable   ;
  43. TCHAR m_sProcessName[MAX_PATH];
  44. //=============================================================================================
  45. //DllMain Procedure
  46. BOOL WINAPI DllMain(
  47. HINSTANCE hModule, 
  48.     DWORD ul_reason_for_call, 
  49.     LPVOID lpReserved
  50. )
  51. {
  52. if(ul_reason_for_call == DLL_PROCESS_ATTACH)
  53. {
  54.   GetModuleFileName(NULL, m_sProcessName, MAX_PATH);
  55. InitializeCriticalSection(&gCriticalSection);
  56. EnterCriticalSection(&gCriticalSection);
  57. {
  58. m_iDllCount ++;
  59. if(m_iDllCount == 1)
  60. m_CheckAcl.SetWindowsVersion();
  61. }
  62. LeaveCriticalSection(&gCriticalSection);
  63. ODS2(m_sProcessName,_T(" Loading ..."));
  64. }
  65. else if(ul_reason_for_call == DLL_PROCESS_DETACH)
  66. {
  67. EnterCriticalSection(&gCriticalSection);
  68. {
  69. m_iDllCount -- ;
  70. }
  71. LeaveCriticalSection(&gCriticalSection);
  72. ODS2(m_sProcessName,_T(" Exit ..."));
  73. }
  74. return TRUE;
  75. }
  76. //=============================================================================================
  77. //Exported Functions
  78. int WSPAPI WSPStartup(
  79. WORD wVersionRequested,
  80. LPWSPDATA lpWSPData,
  81. LPWSAPROTOCOL_INFOW lpProtocolInfo,
  82. WSPUPCALLTABLE upcallTable,
  83. LPWSPPROC_TABLE lpProcTable
  84. )
  85. {
  86. ODS(_T("WSPStartup..."));
  87. ODS(m_CheckAcl.m_bIsWin9x ? _T("IsWin9x") : _T("IsWinNT or Win2000 ..."));
  88.     
  89. if(!m_CheckAcl.m_bIsWin9x && m_CheckAcl.CheckStartup() == XF_QUERY && !QueryAccess())
  90. return SOCKET_ERROR;
  91. TCHAR sLibraryPath[512];
  92.     LPWSPSTARTUP        WSPStartupFunc      = NULL;
  93. HMODULE hLibraryHandle = NULL;
  94.     INT                 ErrorCode           = 0; 
  95. if (!GetHookProvider(lpProtocolInfo, sLibraryPath)
  96. || (hLibraryHandle = LoadLibrary(sLibraryPath)) == NULL
  97. || (WSPStartupFunc = (LPWSPSTARTUP)GetProcAddress(hLibraryHandle, "WSPStartup")) == NULL
  98. )
  99. return WSAEPROVIDERFAILEDINIT;
  100. if ((ErrorCode = WSPStartupFunc(wVersionRequested, lpWSPData, lpProtocolInfo, upcallTable, lpProcTable)) != ERROR_SUCCESS)
  101. return ErrorCode;
  102.     if( !lpProcTable->lpWSPAccept              ||
  103. !lpProcTable->lpWSPAddressToString     ||        
  104. !lpProcTable->lpWSPAsyncSelect         ||   
  105. !lpProcTable->lpWSPBind                ||   
  106. !lpProcTable->lpWSPCancelBlockingCall  || 
  107.         !lpProcTable->lpWSPCleanup             ||     
  108. !lpProcTable->lpWSPCloseSocket         ||    
  109. !lpProcTable->lpWSPConnect             ||
  110. !lpProcTable->lpWSPDuplicateSocket     ||
  111. !lpProcTable->lpWSPEnumNetworkEvents   ||
  112. !lpProcTable->lpWSPEventSelect         ||
  113. !lpProcTable->lpWSPGetOverlappedResult ||
  114. !lpProcTable->lpWSPGetPeerName         ||
  115. !lpProcTable->lpWSPGetSockName         ||
  116. !lpProcTable->lpWSPGetSockOpt          ||   
  117. !lpProcTable->lpWSPGetQOSByName        ||
  118. !lpProcTable->lpWSPIoctl               ||
  119. !lpProcTable->lpWSPJoinLeaf            ||  
  120. !lpProcTable->lpWSPListen              || 
  121.         !lpProcTable->lpWSPRecv                ||     
  122. !lpProcTable->lpWSPRecvDisconnect      ||     
  123. !lpProcTable->lpWSPRecvFrom            ||     
  124. !lpProcTable->lpWSPSelect              ||   
  125. !lpProcTable->lpWSPSend                ||      
  126. !lpProcTable->lpWSPSendDisconnect      ||      
  127. !lpProcTable->lpWSPSendTo              ||      
  128. !lpProcTable->lpWSPSetSockOpt          ||       
  129. !lpProcTable->lpWSPShutdown            ||      
  130. !lpProcTable->lpWSPSocket              ||       
  131. !lpProcTable->lpWSPStringToAddress )
  132. return WSAEINVALIDPROCTABLE;
  133. EnterCriticalSection(&gCriticalSection);
  134. NextProcTable = *lpProcTable;
  135. lpProcTable->lpWSPSocket = WSPSocket;
  136. lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
  137. lpProcTable->lpWSPConnect = WSPConnect;
  138. lpProcTable->lpWSPAccept = WSPAccept;
  139. lpProcTable->lpWSPSend = WSPSend;
  140. lpProcTable->lpWSPSendTo = WSPSendTo;
  141. lpProcTable->lpWSPRecv = WSPRecv;
  142. lpProcTable->lpWSPRecvFrom = WSPRecvFrom;
  143. LeaveCriticalSection(&gCriticalSection);
  144. return 0;
  145. }
  146. int WINAPI XfIoControl(
  147. int iControlType, 
  148. XFILTER_IO_CONTROL *ioControl
  149. )
  150. {
  151. if(iControlType == IO_CONTROL_SET_WORK_MODE)
  152. return CCheckAcl::SetWorkMode(ioControl->iWorkMode);
  153. else if(iControlType == IO_CONTROL_GET_WORK_MODE)
  154. return CCheckAcl::m_iWorkMode;
  155. else if(iControlType == IO_CONTROL_SET_ACL)
  156. return CCheckAcl::SetAcl(ioControl->AclFile);
  157. else if(iControlType == IO_CONTROL_GET_ACL_CHANGE_COUNT)
  158. return gAclChangeCount;
  159. else if(iControlType == IO_CONTROL_SET_GUI_INSTANCE)
  160. {
  161. EnterCriticalSection(&gCriticalSection);
  162. {
  163. CCheckAcl::m_GuiHwnd = ioControl->hwnd;
  164. _tcscpy(CCheckAcl::m_sGuiPathName, m_sProcessName);
  165. }
  166. LeaveCriticalSection(&gCriticalSection);
  167. }
  168. else if(iControlType == IO_CONTROL_GET_SESSION)
  169. {
  170. EnterCriticalSection(&gCriticalSection);
  171. {
  172. *ioControl->session = CCheckAcl::m_SessionBuf[ioControl->isession];
  173. CCheckAcl::m_SessionBuf[ioControl->isession].s = 0;
  174. }
  175. LeaveCriticalSection(&gCriticalSection);
  176. }
  177. else if(iControlType == IO_CONTROL_GET_QUERY_SESSION)
  178. _tcscpy(ioControl->sPathName, m_QuerySession[ioControl->isession].sPathName);
  179. else if(iControlType == IO_CONTROL_SET_QUERY_SESSION)
  180. {
  181. EnterCriticalSection(&gCriticalSection);
  182. {
  183. m_QuerySession[ioControl->isession].status = 0;
  184. }
  185. LeaveCriticalSection(&gCriticalSection);
  186. }
  187. return XERR_SUCCESS;
  188. }
  189. //=============================================================================================
  190. //Socket Private functions
  191. BOOL QueryAccess()
  192. {
  193. ODS(_T("Query Access ..."));
  194. int i;
  195. for(i = 0; i < MAX_QUERY_SESSION; i++)
  196. {
  197. if(m_QuerySession[i].status == 1 
  198. && _tcscpy(m_QuerySession[i].sPathName, m_sProcessName) == 0)
  199. {
  200. while(m_QuerySession[i].status == 1)
  201. {
  202. static int sec = 0;
  203. sec ++;
  204. if(sec > 6000)
  205. return FALSE;
  206. Sleep(100);
  207. }
  208. return TRUE;
  209. }
  210. }
  211. for(i = 0; i < MAX_QUERY_SESSION; i++)
  212. {
  213. if(m_QuerySession[i].status == 0)
  214. {
  215. EnterCriticalSection(&gCriticalSection);
  216. {
  217. m_QuerySession[i].status = 1;
  218. _tcscpy(m_QuerySession[i].sPathName, m_sProcessName);
  219. }
  220. LeaveCriticalSection(&gCriticalSection);
  221. if(!::PostMessage(CCheckAcl::m_GuiHwnd, WM_QUERY_ACL_NOTIFY, i, NULL))
  222. return FALSE;
  223. ODS(_T("Query Access PostMessage ..."));
  224. while(m_QuerySession[i].status == 1)
  225. {
  226. static int sec = 0;
  227. sec ++;
  228. if(sec > 600)
  229. return FALSE;
  230. Sleep(1000);
  231. }
  232. return TRUE;
  233. }
  234. }
  235. if(i >= MAX_QUERY_SESSION)
  236. return FALSE;
  237. return TRUE;
  238. }
  239. BOOL GetHookProvider(
  240. IN WSAPROTOCOL_INFOW *pProtocolInfo, 
  241. OUT TCHAR *sPathName
  242. )
  243. {
  244. TCHAR sItem[21];
  245. GetRightEntryIdItem(pProtocolInfo, sItem);
  246. HKEY hSubkey;
  247. DWORD ulDateLenth = MAX_PATH;
  248. TCHAR sTemp[MAX_PATH];
  249. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_INSTALL_KEY, 0, KEY_ALL_ACCESS, &hSubkey) != ERROR_SUCCESS)
  250. return FALSE;
  251. if (RegQueryValueEx(hSubkey, sItem, 0, NULL, (BYTE*)sTemp, &ulDateLenth)
  252. || ExpandEnvironmentStrings(sTemp, sPathName, ulDateLenth) == 0)
  253. return FALSE;
  254. if(sPathName[0] == '' && sTemp[0] != '')
  255. _tcscpy(sPathName, sTemp);
  256. RegCloseKey(hSubkey);
  257. return TRUE;
  258. }
  259. void GetRightEntryIdItem(
  260. IN WSAPROTOCOL_INFOW *pProtocolInfo, 
  261. OUT TCHAR *sItem
  262. )
  263. {
  264. if(pProtocolInfo->ProtocolChain.ChainLen <= 1)
  265. _stprintf(sItem, _T("%u"), pProtocolInfo->dwCatalogEntryId);
  266. else
  267. _stprintf(sItem, _T("%u"), 
  268. pProtocolInfo->ProtocolChain.ChainEntries[pProtocolInfo->ProtocolChain.ChainLen - 1]);
  269. }
  270. void XfShutdown(SOCKET s)
  271. {
  272. int iError;
  273. if(NextProcTable.lpWSPShutdown(s, SD_BOTH, &iError) != 0)
  274. WSASetLastError(iError);
  275. }
  276. //=============================================================================================
  277. //Winsock 2 service provider hook functions
  278. SOCKET WSPAPI WSPSocket(
  279. int af,                               
  280. int type,                             
  281. int protocol,                         
  282. LPWSAPROTOCOL_INFOW lpProtocolInfo,   
  283. GROUP g,                              
  284. DWORD dwFlags,                        
  285. LPINT lpErrno
  286. )
  287. {
  288. ODS(_T("XFILTER.DLL: WSPSocket ..."));
  289. SOCKET s = NextProcTable.lpWSPSocket(af, type, protocol, lpProtocolInfo, g, dwFlags, lpErrno);
  290. if(s == INVALID_SOCKET)
  291. return s;
  292. if (af == FROM_PROTOCOL_INFO)
  293. af = lpProtocolInfo->iAddressFamily;
  294. if (type == FROM_PROTOCOL_INFO)
  295. type = lpProtocolInfo->iSocketType;
  296. if (protocol == FROM_PROTOCOL_INFO)
  297. protocol = lpProtocolInfo->iProtocol;
  298. m_CheckAcl.CheckSocket(s, af, type, protocol);
  299. return s;
  300. }
  301. int WSPAPI WSPCloseSocket(
  302. SOCKET s,
  303. LPINT lpErrno
  304. )
  305. {
  306. ODS(_T("XFILTER.DLL: WSPCloseSocket ..."));
  307. m_CheckAcl.CheckCloseSocket(s);
  308. return NextProcTable.lpWSPCloseSocket(s, lpErrno);
  309. }
  310. int WSPAPI WSPConnect(
  311. SOCKET s,
  312. const struct sockaddr FAR * name,
  313. int namelen,
  314. LPWSABUF lpCallerData,
  315. LPWSABUF lpCalleeData,
  316. LPQOS lpSQOS,
  317. LPQOS lpGQOS,
  318. LPINT lpErrno
  319. )
  320. {
  321. ODS(_T("XFILTER.DLL: WSPConnect ..."));
  322. if(m_CheckAcl.CheckConnect(s, name, namelen) != XF_PASS)
  323. {
  324. ODS2(_T("Deny the application "), m_sProcessName);
  325. *lpErrno = WSAECONNREFUSED;
  326. return SOCKET_ERROR;
  327. }
  328.  
  329. return NextProcTable.lpWSPConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, lpErrno);
  330. }
  331. SOCKET WSPAPI WSPAccept(
  332. SOCKET s,
  333. struct sockaddr FAR *addr,
  334. LPINT addrlen,
  335. LPCONDITIONPROC lpfnCondition,
  336. DWORD dwCallbackData,
  337. LPINT lpErrno
  338. )
  339. {
  340. ODS(_T("XFILTER.DLL: WSPAccept ..."));
  341. SOCKET news = NextProcTable.lpWSPAccept(s, addr, addrlen, lpfnCondition, dwCallbackData, lpErrno);
  342. if (news != INVALID_SOCKET && m_CheckAcl.CheckAccept(s, news) != XF_PASS)
  343. {
  344. int iError;
  345. if(NextProcTable.lpWSPCloseSocket(news, &iError) != 0)
  346. WSASetLastError(iError);
  347. }
  348. return news;
  349. }
  350. int WSPAPI WSPSend(
  351. SOCKET s,
  352. LPWSABUF lpBuffers,
  353. DWORD dwBufferCount,
  354. LPDWORD lpNumberOfBytesSent,
  355. DWORD dwFlags,
  356. LPWSAOVERLAPPED lpOverlapped,
  357. LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  358. LPWSATHREADID lpThreadId,
  359. LPINT lpErrno
  360. )
  361. {
  362. ODS(_T("XFILTER.DLL: WSPSend ..."));
  363. if (m_CheckAcl.CheckSend(s, lpBuffers[0].buf, lpBuffers[0].len, lpNumberOfBytesSent) != XF_PASS)
  364. {
  365. XfShutdown(s);
  366. *lpErrno = WSAECONNABORTED;
  367. return SOCKET_ERROR;
  368. }
  369. return NextProcTable.lpWSPSend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped
  370. , lpCompletionRoutine, lpThreadId, lpErrno);
  371. }
  372. int WSPAPI WSPSendTo(
  373. SOCKET s,
  374. LPWSABUF lpBuffers,
  375. DWORD dwBufferCount,
  376. LPDWORD lpNumberOfBytesSent,
  377. DWORD dwFlags,
  378. const struct sockaddr FAR * lpTo,
  379. int iTolen,
  380. LPWSAOVERLAPPED lpOverlapped,
  381. LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  382. LPWSATHREADID lpThreadId,
  383. LPINT lpErrno
  384. )
  385. {
  386. ODS(_T("XFILTER.DLL: WSPSendTo ..."));
  387. if (m_CheckAcl.CheckSendTo(s, lpTo, lpBuffers[0].buf, lpBuffers[0].len, lpNumberOfBytesSent) != XF_PASS)
  388. {
  389. XfShutdown(s);
  390. *lpErrno = WSAECONNABORTED;
  391. return SOCKET_ERROR;
  392. }
  393. return NextProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpTo
  394. , iTolen, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);
  395. }
  396. int WSPAPI WSPRecv(
  397. SOCKET s,
  398. LPWSABUF lpBuffers,
  399. DWORD dwBufferCount,
  400. LPDWORD lpNumberOfBytesRecvd,
  401. LPDWORD lpFlags,
  402. LPWSAOVERLAPPED lpOverlapped,
  403. LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  404. LPWSATHREADID lpThreadId,
  405. LPINT lpErrno
  406. )
  407. {
  408. ODS(_T("XFILTER.DLL: WSPRecv ..."));
  409. int iRet;
  410. if(iRet = NextProcTable.lpWSPRecv(s, lpBuffers, 1, lpNumberOfBytesRecvd, lpFlags, lpOverlapped
  411. , lpCompletionRoutine, lpThreadId, lpErrno) == SOCKET_ERROR)
  412. return iRet;
  413. if (m_CheckAcl.CheckRecv(s, lpBuffers[0].buf, lpBuffers[0].len, lpNumberOfBytesRecvd) != XF_PASS)
  414. {
  415. XfShutdown(s);
  416. *lpErrno = WSAECONNABORTED;
  417. return SOCKET_ERROR;
  418. }
  419. return iRet;
  420. }
  421. int WSPAPI WSPRecvFrom (
  422. SOCKET s,
  423. LPWSABUF lpBuffers,
  424. DWORD dwBufferCount,
  425. LPDWORD lpNumberOfBytesRecvd,
  426. LPDWORD lpFlags,
  427. struct sockaddr FAR * lpFrom,
  428. LPINT lpFromlen,
  429. LPWSAOVERLAPPED lpOverlapped,
  430. LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  431. LPWSATHREADID lpThreadId,
  432. LPINT lpErrno
  433. )
  434. {
  435. ODS(_T("XFILTER.DLL: WSPRecvFrom ..."));
  436. int iRet;
  437. if(iRet = NextProcTable.lpWSPRecvFrom(s, lpBuffers, 1, lpNumberOfBytesRecvd, lpFlags, lpFrom
  438. , lpFromlen, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno) == SOCKET_ERROR)
  439. return iRet;
  440. if (m_CheckAcl.CheckRecvFrom(s, lpFrom, lpBuffers[0].buf, lpBuffers[0].len, lpNumberOfBytesRecvd) != XF_PASS)
  441. {
  442. XfShutdown(s);
  443. *lpErrno = WSAECONNABORTED;
  444. return SOCKET_ERROR;
  445. }
  446. return iRet;
  447. }