Kernel Mode Sockets Library

本文介绍了一个完全功能性的内核模式套接字库,允许开发者从内核模式进行连接、发送和接收操作,特别适用于绕过某些类型的防火墙。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



[cpp]  view plain copy
  1. 文章提交:KiSSinGGer (kyller_clemens_at_hotmail.com)  
  2.   
  3. Kernel mode sockets library for the masses  
  4. @ :: deep article ::     Dec 31 2005, 02:27 (UTC+0)    
  5.   
  6. valerino writes: Kernel mode sockets library  
  7.   
  8. It's my birthday today (just turned 31 the 31st december, funny eh ?!), i wanted to publish something,  
  9. it makes me feel alive. Christ lived 33 years only, if i'd be the new Christ  
  10. i've only 2 years left, so better to share my knowledge now :)  
  11.   
  12. Well, here you have a fully functional TDI sockets library. You can connect,  
  13. send, receive, all from your supa-dupa-l333t kernelmode rootkit. Yes, you can  
  14. bypass lame TDI firewalls with this. No, you can't bypass ndis firewalls.  
  15. (read : you can bypass norton's firewall).  
  16.   
  17. Consider that something like this worths $400+ from PCAUSA, and maybe more  
  18. from OSR (KSOCKS)..... enough for a new year's present :)  
  19.   
  20. Usage : you have to hook \\device\tcp yourself and set the global variable TcpIpDevice.  
  21. Then call KSocketInitialize and you're done. Refer to the source for usage.... it shouldn't be hard.  
  22.   
  23. have fun, and happy 2006 to everyone ! Ciao! :)  
  24.   
  25.   
  26.   
  27.   
  28. -----------------------------------------sockets.c------------------------------  
  29.   
  30. //************************************************************************  
  31. //                                                                        
  32. // sockets.c  
  33. // (c) valerino/xOANINO 2003/2004/2005  
  34. //  
  35. // this module implements a generic kernel sockets library.  
  36. // ** Beware that this is optimized for single thread use if REUSE_SOCKETSIRP is defined.**  
  37. //*****************************************************************************  
  38.   
  39. #include "ntifs.h"  
  40.   
  41. #define MODULE "**SOCKETS**"  
  42.   
  43. #ifdef DBG  
  44. #ifdef NO_SOCKETS_DBGMSG  
  45. #undef KDebugPrint  
  46. #define KDebugPrint(DbgLevel,_x)  
  47. #endif  
  48. #endif  
  49.   
  50. /************************************************************************/  
  51. // BOOL KSocketInitialize()  
  52. //  
  53. // Initialize kernelsockets library  
  54. //  
  55. /************************************************************************/  
  56. BOOL KSocketInitialize()  
  57. {  
  58.     ExInitializePagedLookasideList(&LookasideSocketMem, NULL, NULL, 0, 1024, 'lskN', 0);  
  59.     ExInitializePagedLookasideList(&LookasideSocket,NULL,NULL,0,sizeof (KSOCKET),'cosN',0);  
  60.       
  61. #ifdef REUSE_SOCKETSIRP  
  62.     // check for tcpdevice  
  63.     if (!TcpIpDevice)  
  64.         return TRUE;  
  65.       
  66.     // allocate the single irp we use throughout the sockets library  
  67.     SocketsIrp = IoAllocateIrp(TcpIpDevice->StackSize + 1, FALSE);  
  68.     if (!SocketsIrp)  
  69.         return FALSE;  
  70. #endif  
  71.     return TRUE;  
  72. }  
  73.   
  74. /************************************************************************/  
  75. // PVOID KSocketAllocatePool(VOID)  
  76. //  
  77. // Allocate memory from sockets lookaside                                                                      
  78. //  
  79. /************************************************************************/  
  80. PVOID KSocketAllocatePool(VOID)  
  81. {  
  82.     PCHAR    p    = NULL;  
  83.   
  84.     p = ExAllocateFromPagedLookasideList(&LookasideSocketMem);  
  85.     if (p)  
  86.         memset(p, 0, SMALLBUFFER_SIZE);  
  87.     return p;  
  88. }  
  89.   
  90. /************************************************************************/  
  91. // void KSocketFreePool(PVOID pBuffer)  
  92. //  
  93. // Free memory to sockets lookaside                                                                      
  94. //  
  95. /************************************************************************/  
  96. void KSocketFreePool(PVOID pBuffer)  
  97. {  
  98.     ExFreeToPagedLookasideList(&LookasideSocketMem, pBuffer);  
  99. }  
  100.   
  101. /************************************************************************/  
  102. // NTSTATUS KSocketCloseObject(HANDLE Handle, PFILE_OBJECT FileObject)  
  103. //  
  104. // Release a socket object  
  105. //  
  106. /************************************************************************/  
  107. NTSTATUS KSocketCloseObject(HANDLE Handle, PFILE_OBJECT FileObject)  
  108. {  
  109.     NTSTATUS    Status    = STATUS_SUCCESS;  
  110.       
  111.     // dereference referenced object (called for connection and address)  
  112.     if (FileObject)  
  113.         ObDereferenceObject(FileObject);  
  114.       
  115.     // close socket  
  116.     if (Handle)  
  117.         Status = ZwClose(Handle);  
  118.       
  119.     return Status;  
  120. }  
  121.   
  122. /************************************************************************/  
  123. // PFILE_FULL_EA_INFORMATION KSocketBuildEaValues(PVOID EaName, ULONG NameLength, PVOID EaValue,  
  124. //    ULONG ValueLength, PULONG EaLength)  
  125. //  
  126. // Build EA information for the socket object  
  127. //  
  128. /************************************************************************/  
  129. PFILE_FULL_EA_INFORMATION KSocketBuildEaValues(PVOID EaName, ULONG NameLength, PVOID EaValue,  
  130.     ULONG ValueLength, PULONG EaLength)  
  131. {  
  132.     PFILE_FULL_EA_INFORMATION    Ea;  
  133.   
  134.     *EaLength = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) + NameLength + 1 + ValueLength;  
  135.   
  136.     // allocate ea buffer  
  137.     Ea = ExAllocatePool(PagedPool, *EaLength);  
  138.     if (!Ea)  
  139.         return NULL;  
  140.   
  141.     // fill buffer with EA values requested  
  142.     Ea->NextEntryOffset = 0;  
  143.     Ea->Flags = 0;  
  144.     Ea->EaNameLength = (UCHAR) NameLength;  
  145.     Ea->EaValueLength = (USHORT) ValueLength;  
  146.     memcpy (Ea->EaName,EaName,Ea->EaNameLength + 1);  
  147.     if (EaValue && EaLength)  
  148.         memcpy (&Ea->EaName[NameLength + 1],EaValue,ValueLength);  
  149.       
  150.     return Ea;  
  151. }  
  152.   
  153. /************************************************************************/  
  154. // NTSTATUS KSocketOpenAddress(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context)  
  155. //  
  156. // Open address                                                                      
  157. //  
  158. /************************************************************************/  
  159. NTSTATUS KSocketOpenAddress(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context)  
  160. {  
  161.     UNICODE_STRING                Name;  
  162.     OBJECT_ATTRIBUTES            ObjectAttributes;  
  163.     PFILE_FULL_EA_INFORMATION    Ea    = NULL;  
  164.     ULONG                        EaLength;  
  165.     IO_STATUS_BLOCK                Iosb;  
  166.     NTSTATUS                    Status;  
  167.     TA_IP_ADDRESS                Sin;  
  168.   
  169.     // initialize address  
  170.     Sin.TAAddressCount = 1;  
  171.     Sin.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;  
  172.     Sin.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;  
  173.     Sin.Address[0].Address[0].sin_port = 0; // INADDR_ANY;  
  174.     Sin.Address[0].Address[0].in_addr = 0;  
  175.   
  176.     // get EA values for address  
  177.     Ea = KSocketBuildEaValues(TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH, &Sin,  
  178.             sizeof(TA_IP_ADDRESS), &EaLength);  
  179.     if (!Ea)  
  180.     {  
  181.         Status = STATUS_INSUFFICIENT_RESOURCES;  
  182.         goto __exit;  
  183.     }  
  184.   
  185.     // open tcp device  
  186.     RtlInitUnicodeString(&Name, TCPIP_DEVICE);  
  187.     InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, 0);  
  188.     Status = ZwCreateFile(Handle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &Iosb, 0,  
  189.         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,FILE_OPEN_IF,0, Ea, EaLength);  
  190.     if (!NT_SUCCESS(Status))  
  191.         goto __exit;  
  192.       
  193.     Status = ObReferenceObjectByHandle(*Handle, FILE_ANY_ACCESS, 0, KernelMode, FileObject, NULL);  
  194.   
  195. __exit:  
  196.     if (Ea)  
  197.         ExFreePool(Ea);  
  198.   
  199.     return Status;  
  200. }  
  201.   
  202. /************************************************************************/  
  203. // NTSTATUS KSocketOpenConnection(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context)  
  204. //  
  205. // open connection                                                                      
  206. //  
  207. /************************************************************************/  
  208. NTSTATUS KSocketOpenConnection(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context)  
  209. {  
  210.     UNICODE_STRING                Name;  
  211.     OBJECT_ATTRIBUTES            ObjectAttributes;  
  212.     PFILE_FULL_EA_INFORMATION    Ea    = NULL;  
  213.     ULONG                        EaLength;  
  214.     IO_STATUS_BLOCK                Iosb;  
  215.     NTSTATUS                    Status;  
  216.   
  217.     // get EA values for connection  
  218.     Ea = KSocketBuildEaValues(TdiConnectionContext, TDI_CONNECTION_CONTEXT_LENGTH, &Context,  
  219.             sizeof(PKSOCKET), &EaLength);  
  220.     if (!Ea)  
  221.     {  
  222.         Status = STATUS_INSUFFICIENT_RESOURCES;  
  223.         goto __exit;  
  224.     }  
  225.   
  226.     // open tcp device  
  227.     RtlInitUnicodeString(&Name, TCPIP_DEVICE);  
  228.     InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, 0);  
  229.     Status = ZwCreateFile(Handle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &Iosb, 0,  
  230.         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,FILE_OPEN_IF, 0, Ea, EaLength);  
  231.     if (!NT_SUCCESS(Status))  
  232.         goto __exit;  
  233.   
  234.     Status = ObReferenceObjectByHandle(*Handle, FILE_ANY_ACCESS, 0, KernelMode, FileObject, NULL);  
  235.   
  236. __exit:  
  237.     if (Ea)  
  238.         ExFreePool(Ea);  
  239.   
  240.     return Status;  
  241. }  
  242.   
  243. //************************************************************************  
  244. // NTSTATUS KSocketComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)                                                                      
  245. //    
  246. // Socket completion routine  
  247. //************************************************************************/  
  248. NTSTATUS KSocketComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)  
  249. {  
  250.     PMDL mdl = NULL;  
  251.     PMDL nextMdl = NULL;  
  252.     PKSOCKET_CTX Ctx = (PKSOCKET_CTX)Context;  
  253.       
  254.     // set status block  
  255.     Ctx->Iosb.Status = Irp->IoStatus.Status;  
  256.     Ctx->Iosb.Information = Irp->IoStatus.Information;  
  257.       
  258.     // Free any associated MDL.  
  259.     if (Irp->MdlAddress != NULL)  
  260.     {  
  261.         for (mdl = Irp->MdlAddress; mdl != NULL; mdl = nextMdl)  
  262.         {  
  263.             nextMdl = mdl->Next;  
  264.             MmUnlockPages(mdl);  
  265.               
  266.             // This function will also unmap pages.  
  267.             IoFreeMdl(mdl);  
  268.         }  
  269.   
  270.         // set mdl address to null, to prevent iofreeirp to attempt to free it again  
  271.         Irp->MdlAddress = NULL;  
  272.     }  
  273.           
  274. #ifdef REUSE_SOCKETSIRP  
  275.     // set irp for reuse  
  276.     IoReuseIrp (Irp,STATUS_SUCCESS);  
  277. #else  
  278.     // free irp  
  279.     IoFreeIrp (Irp);  
  280. #endif  
  281.     // set event  
  282.     if (Ctx)  
  283.         KeSetEvent (&Ctx->Event,IO_NO_INCREMENT,FALSE);  
  284.       
  285.     return STATUS_MORE_PROCESSING_REQUIRED;  
  286. }  
  287.   
  288. //************************************************************************  
  289. // NTSTATUS KSocketAssociateAddress(HANDLE Address, PFILE_OBJECT Connection)                                                                      
  290. //    
  291. // Associate address  
  292. //************************************************************************/  
  293. NTSTATUS KSocketAssociateAddress(HANDLE Address, PFILE_OBJECT Connection)  
  294. {  
  295.     PDEVICE_OBJECT    DeviceObject;  
  296.     PIRP            Irp = NULL;  
  297.     NTSTATUS        Status = STATUS_TIMEOUT;  
  298.     KSOCKET_CTX        Ctx;  
  299.       
  300.     // initialize event and device  
  301.     KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);      
  302.     DeviceObject = TcpIpDevice;  
  303.       
  304.     // allocate TDI_ASSOCIATE_ADDRESS irp  
  305. #ifdef REUSE_SOCKETSIRP  
  306.     Irp = SocketsIrp;  
  307. #else  
  308.     Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);  
  309. #endif  
  310.     if (!Irp)  
  311.         return STATUS_INSUFFICIENT_RESOURCES;  
  312.       
  313.     // build irp (this set completion routine too)  
  314.     TdiBuildAssociateAddress(Irp, DeviceObject, Connection,KSocketComplete, &Ctx, Address);  
  315.       
  316.     // call tcpip  
  317.     Status = IoCallDriver(DeviceObject, Irp);  
  318.     if (Status == STATUS_PENDING)  
  319.     {  
  320.         // returned status pending  
  321.         Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);  
  322.         if (Status == STATUS_TIMEOUT)  
  323.         {  
  324.             KDebugPrint (1, ("%s ***************** KSocketAssociateAddress timeout occurred ***************** cancelling IRP\n", MODULE));  
  325.                   
  326.             // cancel irp  
  327.             IoCancelIrp(Irp);  
  328.               
  329.             // wait for completion routine to be called  
  330.             KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);  
  331.   
  332.             Status = STATUS_CONNECTION_ABORTED;  
  333.         }  
  334.         else  
  335.         {  
  336.             // ok  
  337.             Status = Ctx.Iosb.Status;  
  338.         }      
  339.     }  
  340.   
  341.     return Status;  
  342. }  
  343.   
  344. //************************************************************************  
  345. // NTSTATUS KSocketConnect(PKSOCKET pSocket, ULONG Address, USHORT Port)  
  346. //    
  347. // Connect socket to address:port                                                                    
  348. //************************************************************************/  
  349. NTSTATUS KSocketConnect(PKSOCKET pSocket, ULONG Address, USHORT Port)  
  350. {  
  351.     PDEVICE_OBJECT        DeviceObject;  
  352.     PIRP                Irp = NULL;  
  353.     NTSTATUS            Status = STATUS_TIMEOUT;  
  354.     KSOCKET_CTX            Ctx;  
  355.     TDI_CONNECTION_INFORMATION    RequestInfo;  
  356.     TA_IP_ADDRESS            RemoteAddress;  
  357.     PFILE_OBJECT            Connection;  
  358.       
  359.     KDebugPrint (2,("%s KSocketConnect called.\n",MODULE));  
  360.   
  361.     if (!pSocket)  
  362.         return STATUS_UNSUCCESSFUL;  
  363.       
  364.     // set parameters  
  365.     Connection = pSocket->ConnectionFile;  
  366.     memset (&RequestInfo,0, sizeof(TDI_CONNECTION_INFORMATION));  
  367.     memset (&RemoteAddress,0,sizeof (TA_IP_ADDRESS));  
  368.       
  369.     RemoteAddress.TAAddressCount = 1;  
  370.     RemoteAddress.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;  
  371.     RemoteAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;  
  372.     RemoteAddress.Address[0].Address[0].sin_port = Port;  
  373.     RemoteAddress.Address[0].Address[0].in_addr = Address;  
  374.       
  375.     RequestInfo.UserDataLength = 0;  
  376.     RequestInfo.UserData = NULL;  
  377.     RequestInfo.OptionsLength = 0;  
  378.     RequestInfo.Options = NULL;  
  379.     RequestInfo.RemoteAddressLength = sizeof(TA_IP_ADDRESS);  
  380.     RequestInfo.RemoteAddress = &RemoteAddress;  
  381.       
  382.     // initialize event and device  
  383.     KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);      
  384.     DeviceObject = TcpIpDevice;  
  385.       
  386.     // allocate TDI_CONNECT irp  
  387. #ifdef REUSE_SOCKETSIRP  
  388.     Irp = SocketsIrp;  
  389. #else  
  390.     Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);  
  391. #endif  
  392.       
  393.     // build irp (this set completion routine too)  
  394.     TdiBuildConnect (Irp, DeviceObject,Connection,KSocketComplete, &Ctx,NULL, &RequestInfo,&RequestInfo);  
  395.       
  396.     // call tcpip  
  397.     Status = IoCallDriver(DeviceObject, Irp);  
  398.     if (Status == STATUS_PENDING)  
  399.     {  
  400.         // returned status pending  
  401.         Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);  
  402.         if (Status == STATUS_TIMEOUT)  
  403.         {  
  404.             KDebugPrint (1, ("%s ***************** KSocketConnect timeout occurred ***************** cancelling IRP\n", MODULE));  
  405.                   
  406.             // cancel irp  
  407.             IoCancelIrp(Irp);  
  408.               
  409.             // wait for completion routine to be called  
  410.             KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);  
  411.   
  412.             Status = STATUS_CONNECTION_ABORTED;  
  413.         }  
  414.         else  
  415.             // ok  
  416.             Status = Ctx.Iosb.Status;  
  417.     }  
  418.       
  419.     if (Status == STATUS_SUCCESS)  
  420.         pSocket->Connected = TRUE;  
  421.       
  422.        return Status;  
  423. }  
  424.   
  425.   
  426. //************************************************************************  
  427. // NTSTATUS KSocketDisconnect(PKSOCKET pSocket  
  428. //    
  429. // Disconnect socket                                                                    
  430. //************************************************************************/  
  431. NTSTATUS KSocketDisconnect(PKSOCKET pSocket)  
  432. {  
  433.     PDEVICE_OBJECT    DeviceObject;  
  434.     PIRP            Irp = NULL;  
  435.     NTSTATUS        Status = STATUS_TIMEOUT;  
  436.     TDI_CONNECTION_INFORMATION    ReqDisconnect;  
  437.     PFILE_OBJECT    Connection;  
  438.     ULONG Flags;  
  439.     KSOCKET_CTX    Ctx;  
  440.       
  441.     // check if socket is already disconnected  
  442.     if (!pSocket)  
  443.         return STATUS_UNSUCCESSFUL;  
  444.       
  445.     if (!pSocket->Connected)  
  446.         return STATUS_ALREADY_DISCONNECTED;  
  447.       
  448.     // set parameters  
  449.     Connection = pSocket->ConnectionFile;  
  450.     memset(&ReqDisconnect,0,sizeof (TDI_CONNECTION_INFORMATION));  
  451.     Flags = TDI_DISCONNECT_ABORT;  
  452.   
  453.        // initialize event and device  
  454.     KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);      
  455.     DeviceObject = TcpIpDevice;  
  456.           
  457.     // allocate TDI_DISCONNECT irp  
  458. #ifdef REUSE_SOCKETSIRP  
  459.     Irp = SocketsIrp;  
  460. #else  
  461.     Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);  
  462. #endif  
  463.     if (!Irp)  
  464.         return STATUS_INSUFFICIENT_RESOURCES;  
  465.       
  466.     // build irp (this set completion routine too)  
  467.     TdiBuildDisconnect (Irp, DeviceObject,Connection,KSocketComplete, &Ctx, NULL,Flags,&ReqDisconnect,&ReqDisconnect);  
  468.       
  469.     // call tcpip  
  470.     Status = IoCallDriver(DeviceObject, Irp);  
  471.     if (Status == STATUS_PENDING)  
  472.     {  
  473.         // returned status pending  
  474.         Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);  
  475.         if (Status == STATUS_TIMEOUT)  
  476.         {  
  477.             KDebugPrint (1, ("%s ***************** KSocketDisconnect timeout occurred ***************** cancelling IRP\n", MODULE));  
  478.                       
  479.             // cancel irp  
  480.             IoCancelIrp(Irp);  
  481.                   
  482.             // wait for completion routine to be called  
  483.             KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);  
  484.   
  485.             Status = STATUS_CONNECTION_ABORTED;  
  486.         }  
  487.         else  
  488.         {  
  489.             // ok  
  490.             Status = Ctx.Iosb.Status;  
  491.         }      
  492.     }  
  493.       
  494.     if (NT_SUCCESS (Status))  
  495.         pSocket->Connected = FALSE;  
  496.       
  497.     return Status;  
  498. }  
  499.   
  500. //************************************************************************  
  501. // NTSTATUS KSocketSend(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesSent)  
  502. //    
  503. // Send buffer thru socket                                                                    
  504. //************************************************************************/  
  505. NTSTATUS KSocketSend(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesSent)  
  506. {  
  507.     PDEVICE_OBJECT    DeviceObject;  
  508.     PFILE_OBJECT    Connection;  
  509.     PIRP            Irp = NULL;  
  510.     NTSTATUS        Status = STATUS_TIMEOUT;  
  511.     KSOCKET_CTX Ctx;  
  512.     PMDL            Mdl;  
  513.       
  514.     KDebugPrint (2,("%s KSocketSend called.\n",MODULE));  
  515.       
  516.     if (!pSocket)  
  517.         return STATUS_UNSUCCESSFUL;  
  518.   
  519.     // set parameters  
  520.     Connection = pSocket->ConnectionFile;  
  521.     *BytesSent = 0;  
  522.       
  523.     // initialize event and device  
  524.     KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);      
  525.     DeviceObject = TcpIpDevice;  
  526.               
  527.     // allocate TDI_SEND irp  
  528. #ifdef REUSE_SOCKETSIRP  
  529.     Irp = SocketsIrp;  
  530. #else  
  531.     Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);  
  532. #endif  
  533.     if (!Irp)  
  534.         return STATUS_INSUFFICIENT_RESOURCES;  
  535.       
  536.     // build mdl  
  537.     Mdl = IoAllocateMdl(Buffer, Size, FALSE, FALSE, NULL);  
  538.     if (!Mdl)  
  539.     {  
  540.         Status = STATUS_INSUFFICIENT_RESOURCES;  
  541.         IoFreeIrp (Irp);  
  542.         return Status;  
  543.     }  
  544.       
  545.     __try  
  546.     {  
  547.         MmProbeAndLockPages(Mdl, KernelMode, IoReadAccess);  
  548.     }  
  549.     __except(EXCEPTION_EXECUTE_HANDLER)  
  550.     {  
  551.         IoFreeMdl (Mdl);  
  552.         IoFreeIrp (Irp);  
  553.         Status = STATUS_UNSUCCESSFUL;  
  554.         return Status;  
  555.     }  
  556.     Mdl->Next = NULL;  
  557.       
  558.     // build irp (this set completion routine too)  
  559.     TdiBuildSend (Irp, DeviceObject,Connection,KSocketComplete, &Ctx,Mdl,0,Size);  
  560.       
  561.     // call tcp  
  562.     Status = IoCallDriver(DeviceObject, Irp);  
  563.     if (Status == STATUS_PENDING)  
  564.     {  
  565.         // returned status pending  
  566.         Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);  
  567.         if (Status == STATUS_TIMEOUT)  
  568.         {  
  569.                KDebugPrint (1, ("%s ***************** KSocketSend timeout occurred ***************** cancelling IRP\n", MODULE));  
  570.                       
  571.             // cancel irp  
  572.             IoCancelIrp(Irp);  
  573.                       
  574.             // wait for completion routine to be called  
  575.             KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);  
  576.             Status = STATUS_CONNECTION_ABORTED;  
  577.         }  
  578.         else  
  579.         {  
  580.             // ok  
  581.             Status = Ctx.Iosb.Status;  
  582.         }  
  583.     }  
  584.       
  585.     // return sent bytes  
  586.     *BytesSent = Ctx.Iosb.Information;  
  587.       
  588.     // check transferred bytes  
  589.     if (Ctx.Iosb.Information != Size)  
  590.         Status = STATUS_CONNECTION_ABORTED;  
  591.   
  592.     if (!NT_SUCCESS(Status))  
  593.     {  
  594.         KDebugPrint(1, ("%s KSocketSend returned error %08x (ReqSent:%d,OkSent:%d)\n", MODULE, Status,  
  595.             Size, *BytesSent));  
  596.     }  
  597.       
  598.     return Status;  
  599. }  
  600.   
  601. //************************************************************************  
  602. // NTSTATUS KSocketReceive(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesReceived, BOOLEAN ReceivePeek)  
  603. //    
  604. // Receive buffer thru socket                                                                    
  605. //************************************************************************/  
  606. NTSTATUS KSocketReceive(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesReceived, BOOLEAN ReceivePeek)  
  607. {  
  608.     PDEVICE_OBJECT    DeviceObject;  
  609.     PFILE_OBJECT    Connection;  
  610.     PIRP            Irp = NULL;  
  611.     NTSTATUS        Status = STATUS_TIMEOUT;  
  612.     PMDL            Mdl;  
  613.     ULONG            Flags;  
  614.     KSOCKET_CTX        Ctx;  
  615.           
  616.     KDebugPrint (2,("%s KSocketReceive called.\n",MODULE));  
  617.       
  618.     if (!pSocket)  
  619.         return STATUS_UNSUCCESSFUL;  
  620.       
  621.     // set parameters  
  622.     Connection = pSocket->ConnectionFile;  
  623.     *BytesReceived = 0;  
  624.       
  625.     if (ReceivePeek)  
  626.         Flags = TDI_RECEIVE_PEEK;  
  627.     else  
  628.         Flags = TDI_RECEIVE_NORMAL;  
  629.       
  630.     // initialize event and device  
  631.     KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);      
  632.     DeviceObject = TcpIpDevice;  
  633.                   
  634.     // allocate TDI_RECEIVE irp  
  635. #ifdef REUSE_SOCKETSIRP  
  636.     Irp = SocketsIrp;  
  637. #else  
  638.     Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);  
  639. #endif  
  640.     if (!Irp)  
  641.         return STATUS_INSUFFICIENT_RESOURCES;  
  642.       
  643.     // build mdl  
  644.     Mdl = IoAllocateMdl(Buffer, Size, FALSE, FALSE, NULL);  
  645.     if (!Mdl)  
  646.     {  
  647.         Status = STATUS_INSUFFICIENT_RESOURCES;  
  648.         IoFreeIrp (Irp);  
  649.         return Status;  
  650.     }  
  651.       
  652.     __try  
  653.     {  
  654.         MmProbeAndLockPages(Mdl, KernelMode, IoWriteAccess);  
  655.     }  
  656.     __except(EXCEPTION_EXECUTE_HANDLER)  
  657.     {  
  658.         IoFreeMdl (Mdl);  
  659.         IoFreeIrp (Irp);  
  660.         Status = STATUS_UNSUCCESSFUL;  
  661.         return Status;  
  662.     }  
  663.     Mdl->Next = NULL;  
  664.       
  665.     // build irp (this set completion routine too)  
  666.     TdiBuildReceive (Irp, DeviceObject,Connection,KSocketComplete, &Ctx,Mdl,Flags,Size);  
  667.       
  668.     // call tcp  
  669.     Status = IoCallDriver(DeviceObject, Irp);  
  670.     if (Status == STATUS_PENDING)  
  671.     {  
  672.         // returned status pending  
  673.         Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);  
  674.         if (Status == STATUS_TIMEOUT)  
  675.         {  
  676.             KDebugPrint (1, ("%s ***************** KSocketReceive timeout occurred ***************** cancelling IRP\n", MODULE));  
  677.                       
  678.             // cancel irp  
  679.             IoCancelIrp(Irp);  
  680.                       
  681.             // wait for completion routine to be called  
  682.             KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);  
  683.   
  684.             Status = STATUS_CONNECTION_ABORTED;  
  685.         }  
  686.         else  
  687.         {  
  688.             // ok  
  689.             Status = Ctx.Iosb.Status;  
  690.         }  
  691.     }  
  692.       
  693.     // return received bytes  
  694.     *BytesReceived = Ctx.Iosb.Information;  
  695.       
  696.     // check received bytes  
  697.     if (Ctx.Iosb.Information == 0)  
  698.         Status = STATUS_CONNECTION_ABORTED;  
  699.   
  700.     if (!NT_SUCCESS(Status))  
  701.     {  
  702.         KDebugPrint(1, ("%s KSocketReceive returned error %08x (ReqRecv:%d,OkRecv:%d)\n", MODULE, Status,  
  703.             Size, *BytesReceived));  
  704.     }  
  705.       
  706.     return Status;  
  707. }  
  708.   
  709. //************************************************************************  
  710. // VOID KSocketClose(PKSOCKET Socket)                                                                      
  711. //    
  712. // Close socket and Release socket memory                                                                    
  713. //************************************************************************/  
  714. VOID KSocketClose(PKSOCKET Socket)  
  715. {  
  716.     if (Socket == NULL)  
  717.     {  
  718.         return;  
  719.     }  
  720.   
  721.     KSocketCloseObject(Socket->TransportAddressHandle, Socket->TransportAddress);  
  722.     KSocketCloseObject(Socket->ConnectionFileHandle, Socket->ConnectionFile);  
  723.   
  724.     ExFreeToPagedLookasideList (&LookasideSocket,Socket);  
  725.   
  726.     Socket = NULL;  
  727. }  
  728.   
  729. //************************************************************************  
  730. // NTSTATUS KSocketCreate(OUT PKSOCKET* Socket)                                                                      
  731. //    
  732. // Create socket                                                                    
  733. //************************************************************************/  
  734. NTSTATUS KSocketCreate(OUT PKSOCKET* Socket)  
  735. {  
  736.     NTSTATUS    Status    = STATUS_SUCCESS;  
  737.     PKSOCKET    iSocket    = NULL;  
  738.   
  739. #ifdef ALWAYS_DISABLESOCKETS  
  740.     KDebugPrint(1,("%s Sockets disabled, connect skipped.\n", MODULE));  
  741.     return STATUS_UNSUCCESSFUL;  
  742. #endif  
  743.       
  744.     // check disabled sockets  
  745.     if (DisableSockets)  
  746.     {  
  747.         KDebugPrint(1,("%s Sockets disabled, connect skipped.\n", MODULE));  
  748.         return STATUS_UNSUCCESSFUL;  
  749.     }  
  750.       
  751.     // handle KAV (crash if not patched)  
  752.     ModulePatchKAV();  
  753.   
  754.     // allocate memory for a new socket  
  755.     iSocket = ExAllocateFromPagedLookasideList(&LookasideSocket);  
  756.     if (!iSocket)  
  757.     {  
  758.         Status = STATUS_INSUFFICIENT_RESOURCES;  
  759.         goto __exit;  
  760.     }  
  761.     memset (iSocket,0, sizeof(KSOCKET));  
  762.   
  763.     // open transport address  
  764.     Status = KSocketOpenAddress(&iSocket->TransportAddressHandle, &iSocket->TransportAddress,  
  765.         iSocket);  
  766.     if (!NT_SUCCESS(Status))  
  767.         goto __exit;  
  768.   
  769.     // create connection endpoint  
  770.     Status = KSocketOpenConnection(&iSocket->ConnectionFileHandle, &iSocket->ConnectionFile,  
  771.                 iSocket);  
  772.     if (!NT_SUCCESS(Status))  
  773.         goto __exit;  
  774.   
  775.     // associate address with connection  
  776.     Status = KSocketAssociateAddress(iSocket->TransportAddressHandle, iSocket->ConnectionFile);  
  777.     if (!NT_SUCCESS(Status))  
  778.         goto __exit;  
  779.       
  780. __exit:  
  781.     if (!NT_SUCCESS(Status))  
  782.     {  
  783.         if (iSocket)  
  784.             KSocketClose(iSocket);  
  785.         *Socket = NULL;  
  786.     }  
  787.     else  
  788.         *Socket = iSocket;  
  789.   
  790.     return Status;  
  791. }  
  792.   
  793. /************************************************************************/  
  794. // NTSTATUS KSocketReadLine(PKSOCKET pSocket, PCHAR buf, SIZE_T maxlen, PSIZE_T ReceivedBytes)  
  795. //  
  796. // Read line (ascii) from network  
  797. //  
  798. /************************************************************************/  
  799. NTSTATUS KSocketReadLine(PKSOCKET pSocket, PCHAR buf, SIZE_T maxlen, PSIZE_T ReceivedBytes)  
  800. {  
  801.     NTSTATUS Status = STATUS_UNSUCCESSFUL;  
  802.     UCHAR c = 0;  
  803.     ULONG i = 0;  
  804.     ULONG received = 0;  
  805.   
  806.     // check params  
  807.     if (!pSocket || !buf || !ReceivedBytes || !maxlen)  
  808.         goto __exit;  
  809.       
  810.     *ReceivedBytes = 0;  
  811.     if (!pSocket->Connected)  
  812.         goto __exit;  
  813.       
  814.     // read line char by char, and stop at EOL  
  815.     memset (buf, 0, maxlen);  
  816.     while (TRUE)  
  817.     {  
  818.         if (i == maxlen)  
  819.             break;  
  820.           
  821.         // get char from socket  
  822.         Status = KSocketReceive (pSocket,&c,1,&received,FALSE);  
  823.         if (!NT_SUCCESS (Status) || received == 0)  
  824.             break;  
  825.           
  826.         // write char into buffer and advance  
  827.         *buf = c;  
  828.         buf++;  
  829.         i++;  
  830.           
  831.         // check for EOL  
  832.         if (c == '\n')  
  833.         {  
  834.             *ReceivedBytes = i;  
  835.             break;  
  836.         }  
  837.     }  
  838.       
  839. __exit:  
  840.     // treat 0 size received as error  
  841.     if (received == 0)  
  842.         Status = STATUS_NO_DATA_DETECTED;  
  843.       
  844.     return Status;  
  845. }  
  846.   
  847. /************************************************************************/  
  848. // NTSTATUS KSocketWriteLine(PKSOCKET pSocket, const char* format, ...)  
  849. //  
  850. // write formatted line (ascii) to network  
  851. //  
  852. /************************************************************************/  
  853. NTSTATUS KSocketWriteLine(PKSOCKET pSocket, const char* format, ...)  
  854. {  
  855.     va_list        ap;  
  856.     char*        buf;  
  857.     ULONG        len;  
  858.     NTSTATUS    Status;  
  859.     SIZE_T        BytesSent    = 0;  
  860.   
  861.     // allocate memory  
  862.     buf = KSocketAllocatePool();  
  863.     if (!buf)  
  864.         return STATUS_INSUFFICIENT_RESOURCES;  
  865.   
  866.     // build line  
  867.     va_start(ap, format);  
  868.     _vsnprintf(buf, SMALLBUFFER_SIZE, format, ap);  
  869.     va_end(ap);  
  870.     len = strlen(buf);  
  871.       
  872.     // send  
  873.     Status = KSocketSend(pSocket, buf, len, &BytesSent);  
  874.   
  875.     // free buffer  
  876.     KSocketFreePool(buf);  
  877.   
  878.     // check if we've sent all bytes  
  879.     if (BytesSent < len)  
  880.         return STATUS_UNSUCCESSFUL;  
  881.       
  882.     return Status;  
  883. }  
  884.   
  885. -----------------------------------------sockets.h------------------------------  
  886.   
  887. #ifndef __sockets_h__  
  888. #define __sockets_h__  
  889.   
  890. #define REUSE_SOCKETSIRP  
  891.   
  892. // debugprint with debuglevel (if dbglevel == debug level, it triggers)  
  893. #if DBG  
  894. #define KDebugPrint(DbgLevel,_x) { \  
  895. if (DbgLevel == DEBUG_LEVEL)        
  896. {                                    
  897. DbgPrint _x;                        
  898. }                                    
  899. }  
  900. #else  
  901. #define KDebugPrint(DbgLevel,_x)  
  902. #endif //DBG  
  903.   
  904. //#define ALWAYS_DISABLESOCKETS  
  905.   
  906. //************************************************************************  
  907. // kernel sockets                                                                      
  908. //                                                                        
  909. //************************************************************************/  
  910. PDEVICE_OBJECT            TcpIpDevice;  
  911.   
  912. typedef struct __tagKSOCKET  
  913. {  
  914.     PFILE_OBJECT                TransportAddress;  
  915.     HANDLE                        TransportAddressHandle;  
  916.     PFILE_OBJECT                ConnectionFile;  
  917.     HANDLE                        ConnectionFileHandle;  
  918.     BOOLEAN                        Connected;  
  919. }KSOCKET, * PKSOCKET;  
  920.   
  921. typedef struct _tagKSOCKET_CTX {  
  922.     KEVENT Event;  
  923.     IO_STATUS_BLOCK Iosb;  
  924. } KSOCKET_CTX, *PKSOCKET_CTX;  
  925.   
  926. PAGED_LOOKASIDE_LIST    LookasideSocketMem;  
  927. PAGED_LOOKASIDE_LIST    LookasideSocket;  
  928. KEVENT                    NoNetworkFailures;  
  929. BOOLEAN                    DisableSockets;                    // flag to disable sockets if needed  
  930. PDRIVER_DISPATCH        OriginalTcpInternalDeviceControl;  
  931. PIRP                    SocketsIrp;  
  932.   
  933. // all paged code except the completion routine  
  934. BOOL                    KSocketInitialize();  
  935. #pragma alloc_text        (PAGEboom,KSocketInitialize)  
  936.   
  937. NTSTATUS                KSocketCreate(OUT PKSOCKET* Socket);  
  938.   
  939. VOID                    KSocketClose(PKSOCKET Socket);  
  940.   
  941. PVOID                    KSocketAllocatePool();  
  942.   
  943. void                    KSocketFreePool(PVOID pBuffer);  
  944.   
  945. NTSTATUS                KSocketSend(PKSOCKET pSocket, PVOID  Buffer, SIZE_T Size,  
  946.                                     PSIZE_T BytesSent);  
  947.   
  948. NTSTATUS                KSocketConnect(PKSOCKET pSocket, ULONG Address, USHORT Port);  
  949. NTSTATUS                KSocketDisconnect(PKSOCKET pSocket);  
  950.   
  951. NTSTATUS                KSocketComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);  
  952.   
  953. NTSTATUS                KSocketReceive(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesReceived,  
  954.                             BOOLEAN ReceivePeek);  
  955.   
  956. NTSTATUS                KSocketReadLine(PKSOCKET pSocket, PCHAR buf, SIZE_T maxlen, PSIZE_T  ReceivedBytes);  
  957.   
  958. NTSTATUS                KSocketWriteLine(PKSOCKET pSocket, const char* format, ...);  
  959.   
  960.   
  961. #endif // __sockets_h__   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值