myfun.cpp
上传用户:yitai_qhd
上传日期:2008-04-24
资源大小:31k
文件大小:12k
开发平台:

Visual C++

  1. #include "myfun.h"
  2. #include "fun.h"
  3. #include "hook.h"
  4. #include "packet.h"
  5. #include "check.h"
  6. #include "memory.h"
  7. #include "windef.h"
  8. #include "stdio.h"
  9. #pragma comment(lib,"ntoskrnl.lib")
  10. #pragma comment(lib,"wdm.lib")
  11. #pragma comment(lib,"libcntpr.lib")
  12. NDISSEND m_pNdisSend = NULL;
  13. NDISREGISTERPROTOCOL m_pNdisRegisterProtocol = NULL;
  14. OPENADAPTERCOMPLETE m_pOpenAdapterComplete = NULL;
  15. NDISOPENADAPTER m_pNdisOpenAdapter = NULL;
  16. NDIS_HANDLE m_TcpipHandle;
  17. RECEIVE m_pNdisReceive = NULL;
  18. SENDPACKET m_pSendHandler = NULL;
  19. WANSENDPACKETS m_pWanSendPackets = NULL;
  20. NDIS_HANDLE m_TcpIpWanHandle = NULL;
  21. VOID NDIS_API
  22. MY_NdisSend(
  23.     PNDIS_STATUS Status,
  24.     NDIS_HANDLE NdisBindingHandle,
  25.     PNDIS_PACKET Packet
  26. )
  27. {
  28.     dprintf(("MY_NdisSendn"));
  29.     m_pNdisSend(Status, NdisBindingHandle, Packet);
  30. }
  31. VOID NDIS_API
  32. MY_NdisRegisterProtocol(
  33.     OUT PNDIS_STATUS Status,
  34.     OUT PNDIS_HANDLE NdisProtocolHandle,
  35.     IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics,
  36.     IN UINT CharacteristicsLength
  37. )
  38. {
  39.     BOOLEAN bHookedTcp = FALSE;
  40.     UNICODE_STRING usTcpName = UNICODE_STRING_CONST("TCPIP");
  41.     dprintf(("MY_NdisRegisterProtocoln"));
  42.     if(m_pNdisRegisterProtocol == NULL)
  43.         return;
  44.     //
  45.     // 判断是否是TCP/IP协议
  46.     //
  47.     if(usTcpName.Length == ProtocolCharacteristics->Name.Length 
  48.         && memcmp(ProtocolCharacteristics->Name.Buffer, usTcpName.Buffer, usTcpName.Length) == 0)
  49.     {
  50.         bHookedTcp = TRUE;
  51.         m_pOpenAdapterComplete = ProtocolCharacteristics->OpenAdapterCompleteHandler;
  52.         ProtocolCharacteristics->OpenAdapterCompleteHandler = MY_OpenAdapterComplete;
  53.         m_pNdisReceive = ProtocolCharacteristics->ReceiveHandler;
  54.         ProtocolCharacteristics->ReceiveHandler = MY_Receive;
  55.     }
  56.     //
  57.     // 转发给系统函数
  58.     //
  59.     m_pNdisRegisterProtocol(
  60.         Status,
  61.         NdisProtocolHandle,
  62.         ProtocolCharacteristics,
  63.         CharacteristicsLength
  64.         );
  65.     if(bHookedTcp)
  66.     {
  67.         m_TcpipHandle = *NdisProtocolHandle;
  68.         bHookedTcp = TRUE;
  69.     }
  70. }
  71. VOID NDIS_API
  72. MY_OpenAdapterComplete(
  73.     IN NDIS_HANDLE ProtocolBindingContext,
  74.     IN NDIS_STATUS Status,
  75.     IN NDIS_STATUS OpenErrorStatus
  76. )
  77. {
  78.     dprintf(("MY_OpenAdapterCompleten"));
  79.     //
  80.     // 调用MY_HookSend对SendHander进行Hook。
  81.     //
  82. if(Status == NDIS_STATUS_SUCCESS)
  83.         MY_HookSend(m_TcpipHandle, MY_SendPacket, (PVOID*)&m_pSendHandler, HOOK_SEND);
  84.     m_pOpenAdapterComplete(
  85.         ProtocolBindingContext,
  86.         Status,
  87.         OpenErrorStatus
  88.         );
  89. }
  90. NDIS_STATUS NDIS_API
  91. MY_Receive(
  92.     IN NDIS_HANDLE NdisBindingContext,
  93.     IN NDIS_HANDLE MacReceiveContext,
  94.     IN PVOID HeaderBuffer,
  95.     IN UINT HeaderBufferSize,
  96.     IN PVOID LookAheadBuffer,
  97.     IN UINT LookaheadBufferSize,
  98.     IN UINT PacketSize
  99. )
  100. {
  101. return 1;
  102. }
  103. VOID NDIS_API
  104. MY_NdisOpenAdapter(
  105. OUT PNDIS_STATUS  Status,
  106. OUT PNDIS_STATUS  OpenErrorStatus,
  107. OUT PNDIS_HANDLE  NdisBindingHandle,
  108. OUT PUINT  SelectedMediumIndex,
  109. IN PNDIS_MEDIUM  MediumArray,
  110. IN UINT  MediumArraySize,
  111. IN NDIS_HANDLE  NdisProtocolHandle,
  112. IN NDIS_HANDLE  ProtocolBindingContext,
  113. IN PNDIS_STRING  AdapterName,
  114. IN UINT  OpenOptions,
  115. IN PSTRING  AddressingInformation  OPTIONAL
  116. )
  117. {
  118. m_pNdisOpenAdapter(
  119. Status,
  120. OpenErrorStatus,
  121. NdisBindingHandle,
  122. SelectedMediumIndex,
  123. MediumArray,
  124. MediumArraySize,
  125. NdisProtocolHandle,
  126. ProtocolBindingContext,
  127. AdapterName,
  128. OpenOptions,
  129. AddressingInformation
  130. );
  131. if(*Status != STATUS_SUCCESS)
  132. return;
  133. if(NdisProtocolHandle == m_TcpipHandle)
  134. MY_HookSend(m_TcpipHandle, MY_SendPacket, (PVOID*)&m_pSendHandler, HOOK_SEND);
  135. else if(NdisProtocolHandle == m_TcpIpWanHandle)
  136. MY_HookSend(m_TcpIpWanHandle, MY_WanSendPackets, (PVOID*)&m_pWanSendPackets, HOOK_SEND_PACKETS);
  137. }
  138. VOID 
  139. MY_HookSend(
  140. IN NDIS_HANDLE ProtocolBlock, 
  141. IN PVOID HookFunction,
  142. OUT PVOID* SendHandler,
  143. IN unsigned char HookType
  144. )
  145. {
  146. if(ProtocolBlock != NULL)
  147. {
  148. PNDIS_PROTOCOL_BLOCK pProtocol = NULL;
  149. PNDIS_OPEN_BLOCK pOpenBlock = NULL;
  150. pProtocol = (PNDIS_PROTOCOL_BLOCK)ProtocolBlock;
  151. pOpenBlock = pProtocol->OpenQueue;
  152. switch(HookType)
  153. {
  154. case HOOK_SEND:
  155. if(pOpenBlock != NULL && pOpenBlock->SendHandler != NULL)
  156. {
  157. *SendHandler = pOpenBlock->SendHandler;
  158. }
  159. while(pOpenBlock != NULL)
  160. {
  161. // pOpenBlock->SendHandler =HookFun;
  162. pOpenBlock = pOpenBlock->ProtocolNextOpen;
  163. }
  164. break;
  165. case HOOK_SEND_PACKETS:
  166. if(pOpenBlock != NULL && pOpenBlock->SendPacketsHandler != NULL)
  167. {
  168. *SendHandler = pOpenBlock->SendPacketsHandler;
  169. }
  170. while(pOpenBlock != NULL)
  171. {
  172. // pOpenBlock->SendPacketsHandler =HookFun;
  173. pOpenBlock = pOpenBlock->ProtocolNextOpen;
  174. }
  175. break;
  176. }
  177. }
  178. }
  179. NDIS_STATUS NDIS_API
  180. MY_SendPacket(
  181. IN NDIS_HANDLE MacBindingHandle,
  182. IN PNDIS_PACKET Packet
  183. )
  184. {
  185. //
  186. // 检查封包的合法性
  187. //
  188. if(CheckSend(Packet) != 0)
  189. return NDIS_STATUS_SUCCESS;//不合法,返回
  190. //
  191. // 转发给系统函数
  192. //
  193. return m_pSendHandler(MacBindingHandle, Packet);
  194. }
  195. VOID NDIS_API
  196. MY_WanSendPackets(
  197. IN NDIS_HANDLE  NdisBindingHandle,
  198. IN PPNDIS_PACKET  PacketArray,
  199. IN UINT  NumberOfPackets
  200. )
  201. {
  202. UINT i;
  203. for(i = 0; i < NumberOfPackets; i++)
  204. {
  205. if(CheckPacket(PacketArray[i], TRUE) != 0)
  206. return;
  207. }
  208. m_pWanSendPackets(NdisBindingHandle, PacketArray, NumberOfPackets);
  209. }
  210. int CheckSend(
  211. IN PNDIS_PACKET packet
  212. )
  213. {
  214. return CheckPacket(packet, TRUE);
  215. }
  216. int CheckPacket(
  217. IN PNDIS_PACKET packet,
  218. IN BOOLEAN IsSend
  219. )
  220. {
  221.   PNDIS_BUFFER  FirstBuffer, Buffer;
  222. UINT TotalPacketLength;
  223. unsigned int EthernetFrameType;
  224. int HeaderLength;
  225. PIP_HEADER pIpHeader;
  226. PETHERNET_FRAME pEthernetFrame;
  227. void* pBiosBuffer;
  228. PICMP_HEADER pIcmpHeader;
  229. PTCP_HEADER pTcpHeader;
  230. PUDP_HEADER pUdpHeader;
  231. UINT PhysicalBufferCount;
  232. UINT BufferCount;
  233. PVOID VirtualAddress;
  234. int Length = 0;
  235. dprintf(("CheckSendn"));
  236. //
  237. // 得到第一个NDIS_BUFFER
  238. //
  239. TotalPacketLength = 0;
  240. NdisQueryPacket(packet
  241. , &PhysicalBufferCount
  242. , &BufferCount
  243. , &FirstBuffer
  244. , &TotalPacketLength
  245. );
  246. if(FirstBuffer == NULL)
  247. return PASS;
  248. Buffer = FirstBuffer;
  249. //
  250. // 解析Ethernet Frame
  251. //
  252. NdisQueryBufferSafe(FirstBuffer, &VirtualAddress, &Length, HighPagePriority);
  253. pEthernetFrame = (PETHERNET_FRAME)VirtualAddress;
  254. EthernetFrameType = ntohs(pEthernetFrame->FrameType);
  255. if(EthernetFrameType != ETHERNET_FRAME_TYPE_TCPIP)//不是IP协议,PASS
  256. return PASS;
  257. //
  258. // 解析Ip Header
  259. //
  260. if((Length - ETHERNET_FRAME_LENGTH) >= IP_HEADER_LENGTH)
  261. {
  262. pIpHeader = (PIP_HEADER)((char*)pEthernetFrame + ETHERNET_FRAME_LENGTH);//跳到IP头
  263. Length = Length - ETHERNET_FRAME_LENGTH;
  264. }
  265. else
  266. {
  267. NdisGetNextBuffer(FirstBuffer, &Buffer);
  268. if(Buffer == NULL)
  269. return PASS;
  270. NdisQueryBufferSafe(Buffer, &VirtualAddress, &Length, HighPagePriority);
  271. if(VirtualAddress == NULL || Length < IP_HEADER_LENGTH)
  272. return PASS;
  273. pIpHeader = (PIP_HEADER)VirtualAddress;
  274. }
  275. HeaderLength = pIpHeader->HeaderLength * HEADER_LENGTH_MULTIPLE;
  276. dprintf(("HeaderLength: %un", HeaderLength));
  277. switch(pIpHeader->Protocol)
  278. {
  279. case PROTOCOL_TCP:
  280. //
  281. // 解析Tcp Header
  282. //
  283. if((Length - HeaderLength) < TCP_HEADER_LENGTH)
  284. {
  285. NdisGetNextBuffer(Buffer, &Buffer);
  286. if(Buffer == NULL) return PASS;
  287. NdisQueryBufferSafe(Buffer, &VirtualAddress, &Length, HighPagePriority);
  288. if(VirtualAddress != NULL && Length >= TCP_HEADER_LENGTH)
  289. {
  290. pTcpHeader = (PTCP_HEADER)(VirtualAddress);
  291. }
  292. else
  293. {
  294. return PASS;
  295. }
  296. }
  297. else
  298. {
  299. pTcpHeader = (PTCP_HEADER)((unsigned long)pIpHeader + HeaderLength);
  300. }
  301. pBiosBuffer = NULL;
  302. if(Buffer != NULL)
  303. {
  304. NdisGetNextBuffer(Buffer, &Buffer);
  305. if(Buffer != NULL)
  306. {
  307. NdisQueryBufferSafe(Buffer, &VirtualAddress, &Length, HighPagePriority);
  308. if(VirtualAddress != NULL && Length >= NETBIOS_MIN_PACKET_SIZE)
  309. pBiosBuffer = (void*)VirtualAddress;
  310. }
  311. //
  312. // 调用CheckTcp对封包的合法性进行审查
  313. //
  314. return CheckTcp(pIpHeader, pTcpHeader, IsSend, TotalPacketLength, pBiosBuffer);
  315. case PROTOCOL_UDP:
  316. //
  317. // 解析UDP Header
  318. //
  319. if((Length - HeaderLength) < UDP_HEADER_LENGTH)
  320. {
  321. //
  322. // if Buffer is NULL or Invalid Address, It can bring a bug check
  323. // 0x1e.
  324. //
  325. NdisGetNextBuffer(Buffer, &Buffer);
  326. if(Buffer == NULL) return PASS;
  327. NdisQueryBufferSafe(Buffer, &VirtualAddress, &Length, HighPagePriority);
  328. if(VirtualAddress != NULL && Length >= UDP_HEADER_LENGTH)
  329. {
  330. pUdpHeader = (PUDP_HEADER)(VirtualAddress);
  331. }
  332. else
  333. {
  334. return PASS;
  335. }
  336. }
  337. else
  338. {
  339. pUdpHeader = (PUDP_HEADER)((unsigned long)pIpHeader + HeaderLength);
  340. }
  341. pBiosBuffer = NULL;
  342. if(Buffer != NULL)
  343. {
  344. NdisGetNextBuffer(Buffer, &Buffer);
  345. if(Buffer != NULL)
  346. {
  347. NdisQueryBufferSafe(Buffer, &VirtualAddress, &Length, HighPagePriority);
  348. if(VirtualAddress != NULL && Length >= NETBIOS_MIN_PACKET_SIZE)
  349. pBiosBuffer = (void*)VirtualAddress;
  350. }
  351. }
  352. //
  353. // 调用 CheckUdp 对封包的合法性进行审查
  354. //
  355. return CheckUdp(pIpHeader, pUdpHeader, IsSend, TotalPacketLength, pBiosBuffer);
  356. case PROTOCOL_ICMP:
  357. //
  358. // 解析 ICMP
  359. //
  360. if((Length - HeaderLength) < ICMP_HEADER_LENGTH)
  361. {
  362. NdisGetNextBuffer(Buffer, &Buffer);
  363. if(Buffer == NULL) return PASS;
  364. NdisQueryBufferSafe(Buffer, &VirtualAddress, &Length, HighPagePriority);
  365. if(VirtualAddress != NULL && Length >= ICMP_HEADER_LENGTH)
  366. pIcmpHeader = (PICMP_HEADER)(VirtualAddress);
  367. else
  368. return PASS;
  369. }
  370. else
  371. {
  372. pIcmpHeader = (PICMP_HEADER)((unsigned long)pIpHeader + HeaderLength);
  373. }
  374. //
  375. // 调用 CheckIcmp 对封包的合法性进行审查
  376. //
  377. return CheckIcmp(pIpHeader, pIcmpHeader, IsSend, TotalPacketLength);
  378. case PROTOCOL_IGMP:
  379. default:
  380. break;
  381. }
  382. return PASS;
  383. }
  384. int CheckRecv(
  385.     IN PVOID HeaderBuffer,
  386.     IN UINT HeaderBufferSize,
  387.     IN PVOID LookAheadBuffer,
  388.     IN UINT LookaheadBufferSize,
  389.     IN UINT PacketSize
  390. )
  391. {
  392.   WORD EthernetFrameType;
  393. WORD LengthCount;
  394. PIP_HEADER pIpHeader;
  395. PETHERNET_FRAME pEthernetFrame;
  396. if(HeaderBufferSize < ETHERNET_FRAME_LENGTH) 
  397. return PASS;
  398. // 解析Ethernet Frame
  399. //
  400. pEthernetFrame = (PETHERNET_FRAME)HeaderBuffer;
  401. EthernetFrameType = ntohs(pEthernetFrame->FrameType);
  402. if(EthernetFrameType != ETHERNET_FRAME_TYPE_TCPIP
  403. || LookaheadBufferSize < IP_HEADER_LENGTH)
  404. return PASS;
  405. // 解析Ip Header
  406. //
  407. pIpHeader = (PIP_HEADER)LookAheadBuffer;
  408. LengthCount = pIpHeader->HeaderLength * HEADER_LENGTH_MULTIPLE;
  409. if(LengthCount == 0)
  410. return PASS;
  411. switch(pIpHeader->Protocol)
  412. {
  413. case PROTOCOL_TCP:
  414. // 解析Tcp Header
  415. //
  416. if(LookaheadBufferSize < (UINT)(LengthCount + TCP_HEADER_LENGTH))
  417. return PASS;
  418. return CheckTcp(pIpHeader
  419. , (PTCP_HEADER)((char*)LookAheadBuffer + LengthCount)
  420. , FALSE
  421. , PacketSize + HeaderBufferSize
  422. , (PVOID)LookaheadBufferSize
  423. );
  424. case PROTOCOL_UDP:
  425. // 解析 Udp Header
  426. //
  427. if(LookaheadBufferSize < (UINT)(LengthCount + UDP_HEADER_LENGTH))
  428. return PASS;
  429. return CheckUdp(pIpHeader
  430. , (PUDP_HEADER)((char*)LookAheadBuffer + LengthCount)
  431. , FALSE
  432. , PacketSize + HeaderBufferSize
  433. , (PVOID)LookaheadBufferSize
  434. );
  435. case PROTOCOL_ICMP:
  436. //
  437. // 解析Icmp Header
  438. //
  439. if(LookaheadBufferSize < (UINT)(LengthCount + ICMP_HEADER_LENGTH))
  440. return PASS;
  441. return CheckIcmp(pIpHeader
  442. , (PICMP_HEADER)((char*)LookAheadBuffer + LengthCount)
  443. , FALSE
  444. , PacketSize + HeaderBufferSize
  445. );
  446. case PROTOCOL_IGMP:
  447. default:
  448. break;
  449. }
  450. return PASS;
  451. }