Kernel mode sockets library for the masses[zt]

    技术2022-05-11  138

    Kernel mode sockets library for the masses By: valerino

    Kernel mode sockets libraryIt's my birthday today (just turned 31 the 31st december, funny eh ?!), i wanted to publish something, it makes me feel alive. Christ lived 33 years only, if i'd be the new Christi've only 2 years left, so better to share my knowledge now :)Well, here you have a fully functional TDI sockets library. You can connect,send, receive, all from your supa-dupa-l333t kernelmode rootkit. Yes, you canbypass lame TDI firewalls with this. No, you can't bypass ndis firewalls.(read : you can bypass norton's firewall).Consider that something like this worths $400+ from PCAUSA, and maybe morefrom OSR (KSOCKS)..... enough for a new year's present :)Usage : you have to hook //device/tcp yourself and set the global variable TcpIpDevice.Then call KSocketInitialize and you're done. Refer to the source for usage.... it shouldn't be hard.have fun, and happy 2006 to everyone ! Ciao! :)-----------------------------------------sockets.c------------------------------//************************************************************************//                                                                      // sockets.c// (c) valerino/xOANINO 2003/2004/2005//// this module implements a generic kernel sockets library. // ** Beware that this is optimized for single thread use if REUSE_SOCKETSIRP is defined.**//*****************************************************************************#include "ntifs.h"#define MODULE "**SOCKETS**"#ifdef DBG#ifdef NO_SOCKETS_DBGMSG#undef KDebugPrint#define KDebugPrint(DbgLevel,_x)#endif#endif/************************************************************************/// BOOL KSocketInitialize()//// Initialize kernelsockets library///************************************************************************/BOOL KSocketInitialize(){    ExInitializePagedLookasideList(&LookasideSocketMem, NULL, NULL, 0, 1024, 'lskN', 0);    ExInitializePagedLookasideList(&LookasideSocket,NULL,NULL,0,sizeof (KSOCKET),'cosN',0);    #ifdef REUSE_SOCKETSIRP    // check for tcpdevice    if (!TcpIpDevice)        return TRUE;        // allocate the single irp we use throughout the sockets library    SocketsIrp = IoAllocateIrp(TcpIpDevice->StackSize + 1, FALSE);    if (!SocketsIrp)        return FALSE;#endif    return TRUE;}/************************************************************************/// PVOID KSocketAllocatePool(VOID)//// Allocate memory from sockets lookaside                                                                     ///************************************************************************/PVOID KSocketAllocatePool(VOID){    PCHAR    p    = NULL;    p = ExAllocateFromPagedLookasideList(&LookasideSocketMem);    if (p)        memset(p, 0, SMALLBUFFER_SIZE);    return p;}/************************************************************************/// void KSocketFreePool(PVOID pBuffer)//// Free memory to sockets lookaside                                                                     ///************************************************************************/void KSocketFreePool(PVOID pBuffer){    ExFreeToPagedLookasideList(&LookasideSocketMem, pBuffer);}/************************************************************************/// NTSTATUS KSocketCloseObject(HANDLE Handle, PFILE_OBJECT FileObject)//// Release a socket object///************************************************************************/NTSTATUS KSocketCloseObject(HANDLE Handle, PFILE_OBJECT FileObject){    NTSTATUS    Status    = STATUS_SUCCESS;        // dereference referenced object (called for connection and address)    if (FileObject)        ObDereferenceObject(FileObject);        // close socket    if (Handle)        Status = ZwClose(Handle);        return Status;}/************************************************************************/// PFILE_FULL_EA_INFORMATION KSocketBuildEaValues(PVOID EaName, ULONG NameLength, PVOID EaValue,//    ULONG ValueLength, PULONG EaLength)//// Build EA information for the socket object///************************************************************************/PFILE_FULL_EA_INFORMATION KSocketBuildEaValues(PVOID EaName, ULONG NameLength, PVOID EaValue,    ULONG ValueLength, PULONG EaLength){    PFILE_FULL_EA_INFORMATION    Ea;    *EaLength = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) + NameLength + 1 + ValueLength;    // allocate ea buffer    Ea = ExAllocatePool(PagedPool, *EaLength);    if (!Ea)        return NULL;    // fill buffer with EA values requested    Ea->NextEntryOffset = 0;    Ea->Flags = 0;    Ea->EaNameLength = (UCHAR) NameLength;    Ea->EaValueLength = (USHORT) ValueLength;    memcpy (Ea->EaName,EaName,Ea->EaNameLength + 1);    if (EaValue && EaLength)        memcpy (&Ea->EaName[NameLength + 1],EaValue,ValueLength);        return Ea;}/************************************************************************/// NTSTATUS KSocketOpenAddress(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context)//// Open address                                                                    ///************************************************************************/NTSTATUS KSocketOpenAddress(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context){    UNICODE_STRING                Name;    OBJECT_ATTRIBUTES            ObjectAttributes;    PFILE_FULL_EA_INFORMATION    Ea    = NULL;    ULONG                        EaLength;    IO_STATUS_BLOCK                Iosb;    NTSTATUS                    Status;    TA_IP_ADDRESS                Sin;    // initialize address    Sin.TAAddressCount = 1;    Sin.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;    Sin.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;    Sin.Address[0].Address[0].sin_port = 0; // INADDR_ANY;    Sin.Address[0].Address[0].in_addr = 0;    // get EA values for address    Ea = KSocketBuildEaValues(TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH, &Sin,            sizeof(TA_IP_ADDRESS), &EaLength);    if (!Ea)    {        Status = STATUS_INSUFFICIENT_RESOURCES;        goto __exit;    }    // open tcp device    RtlInitUnicodeString(&Name, TCPIP_DEVICE);    InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, 0);    Status = ZwCreateFile(Handle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &Iosb, 0,        FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,FILE_OPEN_IF,0, Ea, EaLength);    if (!NT_SUCCESS(Status))        goto __exit;        Status = ObReferenceObjectByHandle(*Handle, FILE_ANY_ACCESS, 0, KernelMode, FileObject, NULL);__exit:    if (Ea)        ExFreePool(Ea);    return Status;}/************************************************************************/// NTSTATUS KSocketOpenConnection(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context)//// open connection                                                                    ///************************************************************************/NTSTATUS KSocketOpenConnection(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context){    UNICODE_STRING                Name;    OBJECT_ATTRIBUTES            ObjectAttributes;    PFILE_FULL_EA_INFORMATION    Ea    = NULL;    ULONG                        EaLength;    IO_STATUS_BLOCK                Iosb;    NTSTATUS                    Status;    // get EA values for connection    Ea = KSocketBuildEaValues(TdiConnectionContext, TDI_CONNECTION_CONTEXT_LENGTH, &Context,            sizeof(PKSOCKET), &EaLength);    if (!Ea)    {        Status = STATUS_INSUFFICIENT_RESOURCES;        goto __exit;    }    // open tcp device    RtlInitUnicodeString(&Name, TCPIP_DEVICE);    InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, 0);    Status = ZwCreateFile(Handle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &Iosb, 0,        FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,FILE_OPEN_IF, 0, Ea, EaLength);    if (!NT_SUCCESS(Status))        goto __exit;    Status = ObReferenceObjectByHandle(*Handle, FILE_ANY_ACCESS, 0, KernelMode, FileObject, NULL);__exit:    if (Ea)        ExFreePool(Ea);    return Status;}//************************************************************************// NTSTATUS KSocketComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)                                                                     //  // Socket completion routine//************************************************************************/NTSTATUS KSocketComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context){    PMDL mdl = NULL;    PMDL nextMdl = NULL;    PKSOCKET_CTX Ctx = (PKSOCKET_CTX)Context;        // set status block    Ctx->Iosb.Status = Irp->IoStatus.Status;    Ctx->Iosb.Information = Irp->IoStatus.Information;        // Free any associated MDL.    if (Irp->MdlAddress != NULL)     {        for (mdl = Irp->MdlAddress; mdl != NULL; mdl = nextMdl)         {            nextMdl = mdl->Next;            MmUnlockPages(mdl);                         // This function will also unmap pages.            IoFreeMdl(mdl);         }        // set mdl address to null, to prevent iofreeirp to attempt to free it again        Irp->MdlAddress = NULL;    }        #ifdef REUSE_SOCKETSIRP    // set irp for reuse    IoReuseIrp (Irp,STATUS_SUCCESS);#else    // free irp    IoFreeIrp (Irp);#endif    // set event    if (Ctx)        KeSetEvent (&Ctx->Event,IO_NO_INCREMENT,FALSE);        return STATUS_MORE_PROCESSING_REQUIRED;}//************************************************************************// NTSTATUS KSocketAssociateAddress(HANDLE Address, PFILE_OBJECT Connection)                                                                     //  // Associate address//************************************************************************/NTSTATUS KSocketAssociateAddress(HANDLE Address, PFILE_OBJECT Connection){    PDEVICE_OBJECT    DeviceObject;    PIRP            Irp = NULL;    NTSTATUS        Status = STATUS_TIMEOUT;    KSOCKET_CTX        Ctx;        // initialize event and device    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);        DeviceObject = TcpIpDevice;        // allocate TDI_ASSOCIATE_ADDRESS irp#ifdef REUSE_SOCKETSIRP    Irp = SocketsIrp;#else    Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);#endif    if (!Irp)        return STATUS_INSUFFICIENT_RESOURCES;        // build irp (this set completion routine too)    TdiBuildAssociateAddress(Irp, DeviceObject, Connection,KSocketComplete, &Ctx, Address);        // call tcpip    Status = IoCallDriver(DeviceObject, Irp);    if (Status == STATUS_PENDING)    {        // returned status pending        Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);        if (Status == STATUS_TIMEOUT)         {            KDebugPrint (1, ("%s ***************** KSocketAssociateAddress timeout occurred ***************** cancelling IRP/n", MODULE));                            // cancel irp            IoCancelIrp(Irp);                        // wait for completion routine to be called            KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);            Status = STATUS_CONNECTION_ABORTED;        }        else         {            // ok            Status = Ctx.Iosb.Status;        }        }    return Status;}//************************************************************************// NTSTATUS KSocketConnect(PKSOCKET pSocket, ULONG Address, USHORT Port)//  // Connect socket to address:port                                                                   //************************************************************************/NTSTATUS KSocketConnect(PKSOCKET pSocket, ULONG Address, USHORT Port){    PDEVICE_OBJECT        DeviceObject;    PIRP                Irp = NULL;    NTSTATUS            Status = STATUS_TIMEOUT;    KSOCKET_CTX            Ctx;    TDI_CONNECTION_INFORMATION    RequestInfo;    TA_IP_ADDRESS            RemoteAddress;    PFILE_OBJECT            Connection;        KDebugPrint (2,("%s KSocketConnect called./n",MODULE));    if (!pSocket)        return STATUS_UNSUCCESSFUL;        // set parameters    Connection = pSocket->ConnectionFile;    memset (&RequestInfo,0, sizeof(TDI_CONNECTION_INFORMATION));    memset (&RemoteAddress,0,sizeof (TA_IP_ADDRESS));        RemoteAddress.TAAddressCount = 1;    RemoteAddress.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;    RemoteAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;    RemoteAddress.Address[0].Address[0].sin_port = Port;    RemoteAddress.Address[0].Address[0].in_addr = Address;        RequestInfo.UserDataLength = 0;    RequestInfo.UserData = NULL;    RequestInfo.OptionsLength = 0;    RequestInfo.Options = NULL;    RequestInfo.RemoteAddressLength = sizeof(TA_IP_ADDRESS);    RequestInfo.RemoteAddress = &RemoteAddress;        // initialize event and device    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);        DeviceObject = TcpIpDevice;        // allocate TDI_CONNECT irp#ifdef REUSE_SOCKETSIRP    Irp = SocketsIrp;#else    Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);#endif        // build irp (this set completion routine too)    TdiBuildConnect (Irp, DeviceObject,Connection,KSocketComplete, &Ctx,NULL, &RequestInfo,&RequestInfo);        // call tcpip    Status = IoCallDriver(DeviceObject, Irp);    if (Status == STATUS_PENDING)    {        // returned status pending        Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);        if (Status == STATUS_TIMEOUT)         {            KDebugPrint (1, ("%s ***************** KSocketConnect timeout occurred ***************** cancelling IRP/n", MODULE));                            // cancel irp            IoCancelIrp(Irp);                        // wait for completion routine to be called            KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);            Status = STATUS_CONNECTION_ABORTED;        }        else             // ok            Status = Ctx.Iosb.Status;    }        if (Status == STATUS_SUCCESS)        pSocket->Connected = TRUE;           return Status;}//************************************************************************// NTSTATUS KSocketDisconnect(PKSOCKET pSocket//  // Disconnect socket                                                                   //************************************************************************/NTSTATUS KSocketDisconnect(PKSOCKET pSocket){    PDEVICE_OBJECT    DeviceObject;    PIRP            Irp = NULL;    NTSTATUS        Status = STATUS_TIMEOUT;    TDI_CONNECTION_INFORMATION    ReqDisconnect;    PFILE_OBJECT    Connection;    ULONG Flags;    KSOCKET_CTX    Ctx;        // check if socket is already disconnected    if (!pSocket)        return STATUS_UNSUCCESSFUL;        if (!pSocket->Connected)        return STATUS_ALREADY_DISCONNECTED;        // set parameters    Connection = pSocket->ConnectionFile;    memset(&ReqDisconnect,0,sizeof (TDI_CONNECTION_INFORMATION));    Flags = TDI_DISCONNECT_ABORT;       // initialize event and device    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);        DeviceObject = TcpIpDevice;            // allocate TDI_DISCONNECT irp#ifdef REUSE_SOCKETSIRP    Irp = SocketsIrp;#else    Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);#endif    if (!Irp)        return STATUS_INSUFFICIENT_RESOURCES;        // build irp (this set completion routine too)    TdiBuildDisconnect (Irp, DeviceObject,Connection,KSocketComplete, &Ctx, NULL,Flags,&ReqDisconnect,&ReqDisconnect);        // call tcpip    Status = IoCallDriver(DeviceObject, Irp);    if (Status == STATUS_PENDING)    {        // returned status pending        Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);        if (Status == STATUS_TIMEOUT)         {            KDebugPrint (1, ("%s ***************** KSocketDisconnect timeout occurred ***************** cancelling IRP/n", MODULE));                                // cancel irp            IoCancelIrp(Irp);                            // wait for completion routine to be called            KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);            Status = STATUS_CONNECTION_ABORTED;        }        else         {            // ok            Status = Ctx.Iosb.Status;        }        }        if (NT_SUCCESS (Status))        pSocket->Connected = FALSE;        return Status;}//************************************************************************// NTSTATUS KSocketSend(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesSent)//  // Send buffer thru socket                                                                   //************************************************************************/NTSTATUS KSocketSend(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesSent){    PDEVICE_OBJECT    DeviceObject;    PFILE_OBJECT    Connection;    PIRP            Irp = NULL;    NTSTATUS        Status = STATUS_TIMEOUT;    KSOCKET_CTX Ctx;    PMDL            Mdl;        KDebugPrint (2,("%s KSocketSend called./n",MODULE));        if (!pSocket)        return STATUS_UNSUCCESSFUL;    // set parameters    Connection = pSocket->ConnectionFile;    *BytesSent = 0;        // initialize event and device    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);        DeviceObject = TcpIpDevice;                // allocate TDI_SEND irp#ifdef REUSE_SOCKETSIRP    Irp = SocketsIrp;#else    Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);#endif    if (!Irp)        return STATUS_INSUFFICIENT_RESOURCES;        // build mdl    Mdl = IoAllocateMdl(Buffer, Size, FALSE, FALSE, NULL);    if (!Mdl)    {        Status = STATUS_INSUFFICIENT_RESOURCES;        IoFreeIrp (Irp);        return Status;    }        __try    {        MmProbeAndLockPages(Mdl, KernelMode, IoReadAccess);    }    __except(EXCEPTION_EXECUTE_HANDLER)    {        IoFreeMdl (Mdl);        IoFreeIrp (Irp);        Status = STATUS_UNSUCCESSFUL;        return Status;    }    Mdl->Next = NULL;        // build irp (this set completion routine too)    TdiBuildSend (Irp, DeviceObject,Connection,KSocketComplete, &Ctx,Mdl,0,Size);        // call tcp    Status = IoCallDriver(DeviceObject, Irp);    if (Status == STATUS_PENDING)    {        // returned status pending        Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);        if (Status == STATUS_TIMEOUT)         {               KDebugPrint (1, ("%s ***************** KSocketSend timeout occurred ***************** cancelling IRP/n", MODULE));                                // cancel irp            IoCancelIrp(Irp);                                // wait for completion routine to be called            KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);            Status = STATUS_CONNECTION_ABORTED;        }        else         {            // ok            Status = Ctx.Iosb.Status;        }    }        // return sent bytes    *BytesSent = Ctx.Iosb.Information;        // check transferred bytes    if (Ctx.Iosb.Information != Size)        Status = STATUS_CONNECTION_ABORTED;    if (!NT_SUCCESS(Status))    {        KDebugPrint(1, ("%s KSocketSend returned error x (ReqSent:%d,OkSent:%d)/n", MODULE, Status,            Size, *BytesSent));    }        return Status;}//************************************************************************// NTSTATUS KSocketReceive(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesReceived, BOOLEAN ReceivePeek)//  // Receive buffer thru socket                                                                   //************************************************************************/NTSTATUS KSocketReceive(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesReceived, BOOLEAN ReceivePeek){    PDEVICE_OBJECT    DeviceObject;    PFILE_OBJECT    Connection;    PIRP            Irp = NULL;    NTSTATUS        Status = STATUS_TIMEOUT;    PMDL            Mdl;    ULONG            Flags;    KSOCKET_CTX        Ctx;            KDebugPrint (2,("%s KSocketReceive called./n",MODULE));        if (!pSocket)        return STATUS_UNSUCCESSFUL;        // set parameters    Connection = pSocket->ConnectionFile;    *BytesReceived = 0;        if (ReceivePeek)        Flags = TDI_RECEIVE_PEEK;    else        Flags = TDI_RECEIVE_NORMAL;        // initialize event and device    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);        DeviceObject = TcpIpDevice;                    // allocate TDI_RECEIVE irp#ifdef REUSE_SOCKETSIRP    Irp = SocketsIrp;#else    Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);#endif    if (!Irp)        return STATUS_INSUFFICIENT_RESOURCES;        // build mdl    Mdl = IoAllocateMdl(Buffer, Size, FALSE, FALSE, NULL);    if (!Mdl)    {        Status = STATUS_INSUFFICIENT_RESOURCES;        IoFreeIrp (Irp);        return Status;    }        __try    {        MmProbeAndLockPages(Mdl, KernelMode, IoWriteAccess);    }    __except(EXCEPTION_EXECUTE_HANDLER)    {        IoFreeMdl (Mdl);        IoFreeIrp (Irp);        Status = STATUS_UNSUCCESSFUL;        return Status;    }    Mdl->Next = NULL;        // build irp (this set completion routine too)    TdiBuildReceive (Irp, DeviceObject,Connection,KSocketComplete, &Ctx,Mdl,Flags,Size);        // call tcp    Status = IoCallDriver(DeviceObject, Irp);    if (Status == STATUS_PENDING)    {        // returned status pending        Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);        if (Status == STATUS_TIMEOUT)         {            KDebugPrint (1, ("%s ***************** KSocketReceive timeout occurred ***************** cancelling IRP/n", MODULE));                                // cancel irp            IoCancelIrp(Irp);                                // wait for completion routine to be called            KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);            Status = STATUS_CONNECTION_ABORTED;        }        else         {            // ok            Status = Ctx.Iosb.Status;        }    }        // return received bytes    *BytesReceived = Ctx.Iosb.Information;        // check received bytes    if (Ctx.Iosb.Information == 0)        Status = STATUS_CONNECTION_ABORTED;    if (!NT_SUCCESS(Status))    {        KDebugPrint(1, ("%s KSocketReceive returned error x (ReqRecv:%d,OkRecv:%d)/n", MODULE, Status,            Size, *BytesReceived));    }        return Status;}//************************************************************************// VOID KSocketClose(PKSOCKET Socket)                                                                     //  // Close socket and Release socket memory                                                                   //************************************************************************/VOID KSocketClose(PKSOCKET Socket){    if (Socket == NULL)    {        return;    }    KSocketCloseObject(Socket->TransportAddressHandle, Socket->TransportAddress);    KSocketCloseObject(Socket->ConnectionFileHandle, Socket->ConnectionFile);    ExFreeToPagedLookasideList (&LookasideSocket,Socket);    Socket = NULL;}//************************************************************************// NTSTATUS KSocketCreate(OUT PKSOCKET* Socket)                                                                     //  // Create socket                                                                   //************************************************************************/NTSTATUS KSocketCreate(OUT PKSOCKET* Socket){    NTSTATUS    Status    = STATUS_SUCCESS;    PKSOCKET    iSocket    = NULL;#ifdef ALWAYS_DISABLESOCKETS    KDebugPrint(1,("%s Sockets disabled, connect skipped./n", MODULE));    return STATUS_UNSUCCESSFUL;#endif        // check disabled sockets    if (DisableSockets)    {        KDebugPrint(1,("%s Sockets disabled, connect skipped./n", MODULE));        return STATUS_UNSUCCESSFUL;    }        // handle KAV (crash if not patched)    ModulePatchKAV();    // allocate memory for a new socket    iSocket = ExAllocateFromPagedLookasideList(&LookasideSocket);    if (!iSocket)    {        Status = STATUS_INSUFFICIENT_RESOURCES;        goto __exit;    }    memset (iSocket,0, sizeof(KSOCKET));    // open transport address    Status = KSocketOpenAddress(&iSocket->TransportAddressHandle, &iSocket->TransportAddress,        iSocket);    if (!NT_SUCCESS(Status))        goto __exit;    // create connection endpoint    Status = KSocketOpenConnection(&iSocket->ConnectionFileHandle, &iSocket->ConnectionFile,                iSocket);    if (!NT_SUCCESS(Status))        goto __exit;    // associate address with connection    Status = KSocketAssociateAddress(iSocket->TransportAddressHandle, iSocket->ConnectionFile);    if (!NT_SUCCESS(Status))        goto __exit;    __exit:    if (!NT_SUCCESS(Status))    {        if (iSocket)            KSocketClose(iSocket);        *Socket = NULL;    }    else        *Socket = iSocket;    return Status;}/************************************************************************/// NTSTATUS KSocketReadLine(PKSOCKET pSocket, PCHAR buf, SIZE_T maxlen, PSIZE_T ReceivedBytes)//// Read line (ascii) from network///************************************************************************/NTSTATUS KSocketReadLine(PKSOCKET pSocket, PCHAR buf, SIZE_T maxlen, PSIZE_T ReceivedBytes){    NTSTATUS Status = STATUS_UNSUCCESSFUL;    UCHAR c = 0;    ULONG i = 0;    ULONG received = 0;    // check params    if (!pSocket || !buf || !ReceivedBytes || !maxlen)        goto __exit;        *ReceivedBytes = 0;    if (!pSocket->Connected)        goto __exit;        // read line char by char, and stop at EOL    memset (buf, 0, maxlen);    while (TRUE)    {        if (i == maxlen)            break;                // get char from socket        Status = KSocketReceive (pSocket,&c,1,&received,FALSE);        if (!NT_SUCCESS (Status) || received == 0)            break;                // write char into buffer and advance        *buf = c;        buf++;        i++;                // check for EOL        if (c == '/n')        {            *ReceivedBytes = i;            break;        }    }    __exit:    // treat 0 size received as error    if (received == 0)        Status = STATUS_NO_DATA_DETECTED;        return Status;}/************************************************************************/// NTSTATUS KSocketWriteLine(PKSOCKET pSocket, const char* format, ...)//// write formatted line (ascii) to network///************************************************************************/NTSTATUS KSocketWriteLine(PKSOCKET pSocket, const char* format, ...){    va_list        ap;    char*        buf;    ULONG        len;    NTSTATUS    Status;    SIZE_T        BytesSent    = 0;    // allocate memory    buf = KSocketAllocatePool();    if (!buf)        return STATUS_INSUFFICIENT_RESOURCES;    // build line    va_start(ap, format);    _vsnprintf(buf, SMALLBUFFER_SIZE, format, ap);    va_end(ap);    len = strlen(buf);        // send    Status = KSocketSend(pSocket, buf, len, &BytesSent);    // free buffer    KSocketFreePool(buf);    // check if we've sent all bytes    if (BytesSent < len)        return STATUS_UNSUCCESSFUL;        return Status;}-----------------------------------------sockets.h------------------------------#ifndef __sockets_h__#define __sockets_h__#define REUSE_SOCKETSIRP// debugprint with debuglevel (if dbglevel == debug level, it triggers)#if DBG#define KDebugPrint(DbgLevel,_x) { /if (DbgLevel == DEBUG_LEVEL)       {                                  DbgPrint _x;                       }                                  }#else#define KDebugPrint(DbgLevel,_x)#endif //DBG//#define ALWAYS_DISABLESOCKETS//************************************************************************// kernel sockets                                                                     //                                                                      //************************************************************************/PDEVICE_OBJECT            TcpIpDevice;typedef struct __tagKSOCKET{    PFILE_OBJECT                TransportAddress;    HANDLE                        TransportAddressHandle;    PFILE_OBJECT                ConnectionFile;    HANDLE                        ConnectionFileHandle;    BOOLEAN                        Connected;}KSOCKET, * PKSOCKET;typedef struct _tagKSOCKET_CTX {    KEVENT Event;    IO_STATUS_BLOCK Iosb;} KSOCKET_CTX, *PKSOCKET_CTX;PAGED_LOOKASIDE_LIST    LookasideSocketMem;PAGED_LOOKASIDE_LIST    LookasideSocket;KEVENT                    NoNetworkFailures;BOOLEAN                    DisableSockets;                    // flag to disable sockets if neededPDRIVER_DISPATCH        OriginalTcpInternalDeviceControl;PIRP                    SocketsIrp;// all paged code except the completion routineBOOL                    KSocketInitialize();#pragma alloc_text        (PAGEboom,KSocketInitialize)NTSTATUS                KSocketCreate(OUT PKSOCKET* Socket);VOID                    KSocketClose(PKSOCKET Socket);PVOID                    KSocketAllocatePool();void                    KSocketFreePool(PVOID pBuffer);NTSTATUS                KSocketSend(PKSOCKET pSocket, PVOID  Buffer, SIZE_T Size,                                    PSIZE_T BytesSent);NTSTATUS                KSocketConnect(PKSOCKET pSocket, ULONG Address, USHORT Port);NTSTATUS                KSocketDisconnect(PKSOCKET pSocket);NTSTATUS                KSocketComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);NTSTATUS                KSocketReceive(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesReceived,                            BOOLEAN ReceivePeek);NTSTATUS                KSocketReadLine(PKSOCKET pSocket, PCHAR buf, SIZE_T maxlen, PSIZE_T  ReceivedBytes);NTSTATUS                KSocketWriteLine(PKSOCKET pSocket, const char* format, ...);#endif // __sockets_h__

    Kernel mode sockets libraryIt's my birthday today (just turned 31 the 31st december, funny eh ?!), i wanted to publish something, it makes me feel alive. Christ lived 33 years only, if i'd be the new Christi've only 2 years left, so better to share my knowledge now :)Well, here you have a fully functional TDI sockets library. You can connect,send, receive, all from your supa-dupa-l333t kernelmode rootkit. Yes, you canbypass lame TDI firewalls with this. No, you can't bypass ndis firewalls.(read : you can bypass norton's firewall).Consider that something like this worths $400+ from PCAUSA, and maybe morefrom OSR (KSOCKS)..... enough for a new year's present :)Usage : you have to hook //device/tcp yourself and set the global variable TcpIpDevice.Then call KSocketInitialize and you're done. Refer to the source for usage.... it shouldn't be hard.have fun, and happy 2006 to everyone ! Ciao! :)-----------------------------------------sockets.c------------------------------//************************************************************************//                                                                      // sockets.c// (c) valerino/xOANINO 2003/2004/2005//// this module implements a generic kernel sockets library. // ** Beware that this is optimized for single thread use if REUSE_SOCKETSIRP is defined.**//*****************************************************************************#include "ntifs.h"#define MODULE "**SOCKETS**"#ifdef DBG#ifdef NO_SOCKETS_DBGMSG#undef KDebugPrint#define KDebugPrint(DbgLevel,_x)#endif#endif/************************************************************************/// BOOL KSocketInitialize()//// Initialize kernelsockets library///************************************************************************/BOOL KSocketInitialize(){    ExInitializePagedLookasideList(&LookasideSocketMem, NULL, NULL, 0, 1024, 'lskN', 0);    ExInitializePagedLookasideList(&LookasideSocket,NULL,NULL,0,sizeof (KSOCKET),'cosN',0);    #ifdef REUSE_SOCKETSIRP    // check for tcpdevice    if (!TcpIpDevice)        return TRUE;        // allocate the single irp we use throughout the sockets library    SocketsIrp = IoAllocateIrp(TcpIpDevice->StackSize + 1, FALSE);    if (!SocketsIrp)        return FALSE;#endif    return TRUE;}/************************************************************************/// PVOID KSocketAllocatePool(VOID)//// Allocate memory from sockets lookaside                                                                     ///************************************************************************/PVOID KSocketAllocatePool(VOID){    PCHAR    p    = NULL;    p = ExAllocateFromPagedLookasideList(&LookasideSocketMem);    if (p)        memset(p, 0, SMALLBUFFER_SIZE);    return p;}/************************************************************************/// void KSocketFreePool(PVOID pBuffer)//// Free memory to sockets lookaside                                                                     ///************************************************************************/void KSocketFreePool(PVOID pBuffer){    ExFreeToPagedLookasideList(&LookasideSocketMem, pBuffer);}/************************************************************************/// NTSTATUS KSocketCloseObject(HANDLE Handle, PFILE_OBJECT FileObject)//// Release a socket object///************************************************************************/NTSTATUS KSocketCloseObject(HANDLE Handle, PFILE_OBJECT FileObject){    NTSTATUS    Status    = STATUS_SUCCESS;        // dereference referenced object (called for connection and address)    if (FileObject)        ObDereferenceObject(FileObject);        // close socket    if (Handle)        Status = ZwClose(Handle);        return Status;}/************************************************************************/// PFILE_FULL_EA_INFORMATION KSocketBuildEaValues(PVOID EaName, ULONG NameLength, PVOID EaValue,//    ULONG ValueLength, PULONG EaLength)//// Build EA information for the socket object///************************************************************************/PFILE_FULL_EA_INFORMATION KSocketBuildEaValues(PVOID EaName, ULONG NameLength, PVOID EaValue,    ULONG ValueLength, PULONG EaLength){    PFILE_FULL_EA_INFORMATION    Ea;    *EaLength = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName[0]) + NameLength + 1 + ValueLength;    // allocate ea buffer    Ea = ExAllocatePool(PagedPool, *EaLength);    if (!Ea)        return NULL;    // fill buffer with EA values requested    Ea->NextEntryOffset = 0;    Ea->Flags = 0;    Ea->EaNameLength = (UCHAR) NameLength;    Ea->EaValueLength = (USHORT) ValueLength;    memcpy (Ea->EaName,EaName,Ea->EaNameLength + 1);    if (EaValue && EaLength)        memcpy (&Ea->EaName[NameLength + 1],EaValue,ValueLength);        return Ea;}/************************************************************************/// NTSTATUS KSocketOpenAddress(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context)//// Open address                                                                    ///************************************************************************/NTSTATUS KSocketOpenAddress(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context){    UNICODE_STRING                Name;    OBJECT_ATTRIBUTES            ObjectAttributes;    PFILE_FULL_EA_INFORMATION    Ea    = NULL;    ULONG                        EaLength;    IO_STATUS_BLOCK                Iosb;    NTSTATUS                    Status;    TA_IP_ADDRESS                Sin;    // initialize address    Sin.TAAddressCount = 1;    Sin.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;    Sin.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;    Sin.Address[0].Address[0].sin_port = 0; // INADDR_ANY;    Sin.Address[0].Address[0].in_addr = 0;    // get EA values for address    Ea = KSocketBuildEaValues(TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH, &Sin,            sizeof(TA_IP_ADDRESS), &EaLength);    if (!Ea)    {        Status = STATUS_INSUFFICIENT_RESOURCES;        goto __exit;    }    // open tcp device    RtlInitUnicodeString(&Name, TCPIP_DEVICE);    InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, 0);    Status = ZwCreateFile(Handle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &Iosb, 0,        FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,FILE_OPEN_IF,0, Ea, EaLength);    if (!NT_SUCCESS(Status))        goto __exit;        Status = ObReferenceObjectByHandle(*Handle, FILE_ANY_ACCESS, 0, KernelMode, FileObject, NULL);__exit:    if (Ea)        ExFreePool(Ea);    return Status;}/************************************************************************/// NTSTATUS KSocketOpenConnection(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context)//// open connection                                                                    ///************************************************************************/NTSTATUS KSocketOpenConnection(PHANDLE Handle, PFILE_OBJECT* FileObject, PVOID Context){    UNICODE_STRING                Name;    OBJECT_ATTRIBUTES            ObjectAttributes;    PFILE_FULL_EA_INFORMATION    Ea    = NULL;    ULONG                        EaLength;    IO_STATUS_BLOCK                Iosb;    NTSTATUS                    Status;    // get EA values for connection    Ea = KSocketBuildEaValues(TdiConnectionContext, TDI_CONNECTION_CONTEXT_LENGTH, &Context,            sizeof(PKSOCKET), &EaLength);    if (!Ea)    {        Status = STATUS_INSUFFICIENT_RESOURCES;        goto __exit;    }    // open tcp device    RtlInitUnicodeString(&Name, TCPIP_DEVICE);    InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, 0);    Status = ZwCreateFile(Handle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &Iosb, 0,        FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,FILE_OPEN_IF, 0, Ea, EaLength);    if (!NT_SUCCESS(Status))        goto __exit;    Status = ObReferenceObjectByHandle(*Handle, FILE_ANY_ACCESS, 0, KernelMode, FileObject, NULL);__exit:    if (Ea)        ExFreePool(Ea);    return Status;}//************************************************************************// NTSTATUS KSocketComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)                                                                     //  // Socket completion routine//************************************************************************/NTSTATUS KSocketComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context){    PMDL mdl = NULL;    PMDL nextMdl = NULL;    PKSOCKET_CTX Ctx = (PKSOCKET_CTX)Context;        // set status block    Ctx->Iosb.Status = Irp->IoStatus.Status;    Ctx->Iosb.Information = Irp->IoStatus.Information;        // Free any associated MDL.    if (Irp->MdlAddress != NULL)     {        for (mdl = Irp->MdlAddress; mdl != NULL; mdl = nextMdl)         {            nextMdl = mdl->Next;            MmUnlockPages(mdl);                         // This function will also unmap pages.            IoFreeMdl(mdl);         }        // set mdl address to null, to prevent iofreeirp to attempt to free it again        Irp->MdlAddress = NULL;    }        #ifdef REUSE_SOCKETSIRP    // set irp for reuse    IoReuseIrp (Irp,STATUS_SUCCESS);#else    // free irp    IoFreeIrp (Irp);#endif    // set event    if (Ctx)        KeSetEvent (&Ctx->Event,IO_NO_INCREMENT,FALSE);        return STATUS_MORE_PROCESSING_REQUIRED;}//************************************************************************// NTSTATUS KSocketAssociateAddress(HANDLE Address, PFILE_OBJECT Connection)                                                                     //  // Associate address//************************************************************************/NTSTATUS KSocketAssociateAddress(HANDLE Address, PFILE_OBJECT Connection){    PDEVICE_OBJECT    DeviceObject;    PIRP            Irp = NULL;    NTSTATUS        Status = STATUS_TIMEOUT;    KSOCKET_CTX        Ctx;        // initialize event and device    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);        DeviceObject = TcpIpDevice;        // allocate TDI_ASSOCIATE_ADDRESS irp#ifdef REUSE_SOCKETSIRP    Irp = SocketsIrp;#else    Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);#endif    if (!Irp)        return STATUS_INSUFFICIENT_RESOURCES;        // build irp (this set completion routine too)    TdiBuildAssociateAddress(Irp, DeviceObject, Connection,KSocketComplete, &Ctx, Address);        // call tcpip    Status = IoCallDriver(DeviceObject, Irp);    if (Status == STATUS_PENDING)    {        // returned status pending        Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);        if (Status == STATUS_TIMEOUT)         {            KDebugPrint (1, ("%s ***************** KSocketAssociateAddress timeout occurred ***************** cancelling IRP/n", MODULE));                            // cancel irp            IoCancelIrp(Irp);                        // wait for completion routine to be called            KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);            Status = STATUS_CONNECTION_ABORTED;        }        else         {            // ok            Status = Ctx.Iosb.Status;        }        }    return Status;}//************************************************************************// NTSTATUS KSocketConnect(PKSOCKET pSocket, ULONG Address, USHORT Port)//  // Connect socket to address:port                                                                   //************************************************************************/NTSTATUS KSocketConnect(PKSOCKET pSocket, ULONG Address, USHORT Port){    PDEVICE_OBJECT        DeviceObject;    PIRP                Irp = NULL;    NTSTATUS            Status = STATUS_TIMEOUT;    KSOCKET_CTX            Ctx;    TDI_CONNECTION_INFORMATION    RequestInfo;    TA_IP_ADDRESS            RemoteAddress;    PFILE_OBJECT            Connection;        KDebugPrint (2,("%s KSocketConnect called./n",MODULE));    if (!pSocket)        return STATUS_UNSUCCESSFUL;        // set parameters    Connection = pSocket->ConnectionFile;    memset (&RequestInfo,0, sizeof(TDI_CONNECTION_INFORMATION));    memset (&RemoteAddress,0,sizeof (TA_IP_ADDRESS));        RemoteAddress.TAAddressCount = 1;    RemoteAddress.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;    RemoteAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;    RemoteAddress.Address[0].Address[0].sin_port = Port;    RemoteAddress.Address[0].Address[0].in_addr = Address;        RequestInfo.UserDataLength = 0;    RequestInfo.UserData = NULL;    RequestInfo.OptionsLength = 0;    RequestInfo.Options = NULL;    RequestInfo.RemoteAddressLength = sizeof(TA_IP_ADDRESS);    RequestInfo.RemoteAddress = &RemoteAddress;        // initialize event and device    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);        DeviceObject = TcpIpDevice;        // allocate TDI_CONNECT irp#ifdef REUSE_SOCKETSIRP    Irp = SocketsIrp;#else    Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);#endif        // build irp (this set completion routine too)    TdiBuildConnect (Irp, DeviceObject,Connection,KSocketComplete, &Ctx,NULL, &RequestInfo,&RequestInfo);        // call tcpip    Status = IoCallDriver(DeviceObject, Irp);    if (Status == STATUS_PENDING)    {        // returned status pending        Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);        if (Status == STATUS_TIMEOUT)         {            KDebugPrint (1, ("%s ***************** KSocketConnect timeout occurred ***************** cancelling IRP/n", MODULE));                            // cancel irp            IoCancelIrp(Irp);                        // wait for completion routine to be called            KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);            Status = STATUS_CONNECTION_ABORTED;        }        else             // ok            Status = Ctx.Iosb.Status;    }        if (Status == STATUS_SUCCESS)        pSocket->Connected = TRUE;           return Status;}//************************************************************************// NTSTATUS KSocketDisconnect(PKSOCKET pSocket//  // Disconnect socket                                                                   //************************************************************************/NTSTATUS KSocketDisconnect(PKSOCKET pSocket){    PDEVICE_OBJECT    DeviceObject;    PIRP            Irp = NULL;    NTSTATUS        Status = STATUS_TIMEOUT;    TDI_CONNECTION_INFORMATION    ReqDisconnect;    PFILE_OBJECT    Connection;    ULONG Flags;    KSOCKET_CTX    Ctx;        // check if socket is already disconnected    if (!pSocket)        return STATUS_UNSUCCESSFUL;        if (!pSocket->Connected)        return STATUS_ALREADY_DISCONNECTED;        // set parameters    Connection = pSocket->ConnectionFile;    memset(&ReqDisconnect,0,sizeof (TDI_CONNECTION_INFORMATION));    Flags = TDI_DISCONNECT_ABORT;       // initialize event and device    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);        DeviceObject = TcpIpDevice;            // allocate TDI_DISCONNECT irp#ifdef REUSE_SOCKETSIRP    Irp = SocketsIrp;#else    Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);#endif    if (!Irp)        return STATUS_INSUFFICIENT_RESOURCES;        // build irp (this set completion routine too)    TdiBuildDisconnect (Irp, DeviceObject,Connection,KSocketComplete, &Ctx, NULL,Flags,&ReqDisconnect,&ReqDisconnect);        // call tcpip    Status = IoCallDriver(DeviceObject, Irp);    if (Status == STATUS_PENDING)    {        // returned status pending        Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);        if (Status == STATUS_TIMEOUT)         {            KDebugPrint (1, ("%s ***************** KSocketDisconnect timeout occurred ***************** cancelling IRP/n", MODULE));                                // cancel irp            IoCancelIrp(Irp);                            // wait for completion routine to be called            KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);            Status = STATUS_CONNECTION_ABORTED;        }        else         {            // ok            Status = Ctx.Iosb.Status;        }        }        if (NT_SUCCESS (Status))        pSocket->Connected = FALSE;        return Status;}//************************************************************************// NTSTATUS KSocketSend(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesSent)//  // Send buffer thru socket                                                                   //************************************************************************/NTSTATUS KSocketSend(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesSent){    PDEVICE_OBJECT    DeviceObject;    PFILE_OBJECT    Connection;    PIRP            Irp = NULL;    NTSTATUS        Status = STATUS_TIMEOUT;    KSOCKET_CTX Ctx;    PMDL            Mdl;        KDebugPrint (2,("%s KSocketSend called./n",MODULE));        if (!pSocket)        return STATUS_UNSUCCESSFUL;    // set parameters    Connection = pSocket->ConnectionFile;    *BytesSent = 0;        // initialize event and device    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);        DeviceObject = TcpIpDevice;                // allocate TDI_SEND irp#ifdef REUSE_SOCKETSIRP    Irp = SocketsIrp;#else    Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);#endif    if (!Irp)        return STATUS_INSUFFICIENT_RESOURCES;        // build mdl    Mdl = IoAllocateMdl(Buffer, Size, FALSE, FALSE, NULL);    if (!Mdl)    {        Status = STATUS_INSUFFICIENT_RESOURCES;        IoFreeIrp (Irp);        return Status;    }        __try    {        MmProbeAndLockPages(Mdl, KernelMode, IoReadAccess);    }    __except(EXCEPTION_EXECUTE_HANDLER)    {        IoFreeMdl (Mdl);        IoFreeIrp (Irp);        Status = STATUS_UNSUCCESSFUL;        return Status;    }    Mdl->Next = NULL;        // build irp (this set completion routine too)    TdiBuildSend (Irp, DeviceObject,Connection,KSocketComplete, &Ctx,Mdl,0,Size);        // call tcp    Status = IoCallDriver(DeviceObject, Irp);    if (Status == STATUS_PENDING)    {        // returned status pending        Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);        if (Status == STATUS_TIMEOUT)         {               KDebugPrint (1, ("%s ***************** KSocketSend timeout occurred ***************** cancelling IRP/n", MODULE));                                // cancel irp            IoCancelIrp(Irp);                                // wait for completion routine to be called            KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);            Status = STATUS_CONNECTION_ABORTED;        }        else         {            // ok            Status = Ctx.Iosb.Status;        }    }        // return sent bytes    *BytesSent = Ctx.Iosb.Information;        // check transferred bytes    if (Ctx.Iosb.Information != Size)        Status = STATUS_CONNECTION_ABORTED;    if (!NT_SUCCESS(Status))    {        KDebugPrint(1, ("%s KSocketSend returned error x (ReqSent:%d,OkSent:%d)/n", MODULE, Status,            Size, *BytesSent));    }        return Status;}//************************************************************************// NTSTATUS KSocketReceive(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesReceived, BOOLEAN ReceivePeek)//  // Receive buffer thru socket                                                                   //************************************************************************/NTSTATUS KSocketReceive(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesReceived, BOOLEAN ReceivePeek){    PDEVICE_OBJECT    DeviceObject;    PFILE_OBJECT    Connection;    PIRP            Irp = NULL;    NTSTATUS        Status = STATUS_TIMEOUT;    PMDL            Mdl;    ULONG            Flags;    KSOCKET_CTX        Ctx;            KDebugPrint (2,("%s KSocketReceive called./n",MODULE));        if (!pSocket)        return STATUS_UNSUCCESSFUL;        // set parameters    Connection = pSocket->ConnectionFile;    *BytesReceived = 0;        if (ReceivePeek)        Flags = TDI_RECEIVE_PEEK;    else        Flags = TDI_RECEIVE_NORMAL;        // initialize event and device    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);        DeviceObject = TcpIpDevice;                    // allocate TDI_RECEIVE irp#ifdef REUSE_SOCKETSIRP    Irp = SocketsIrp;#else    Irp = IoAllocateIrp(DeviceObject->StackSize + 1, FALSE);#endif    if (!Irp)        return STATUS_INSUFFICIENT_RESOURCES;        // build mdl    Mdl = IoAllocateMdl(Buffer, Size, FALSE, FALSE, NULL);    if (!Mdl)    {        Status = STATUS_INSUFFICIENT_RESOURCES;        IoFreeIrp (Irp);        return Status;    }        __try    {        MmProbeAndLockPages(Mdl, KernelMode, IoWriteAccess);    }    __except(EXCEPTION_EXECUTE_HANDLER)    {        IoFreeMdl (Mdl);        IoFreeIrp (Irp);        Status = STATUS_UNSUCCESSFUL;        return Status;    }    Mdl->Next = NULL;        // build irp (this set completion routine too)    TdiBuildReceive (Irp, DeviceObject,Connection,KSocketComplete, &Ctx,Mdl,Flags,Size);        // call tcp    Status = IoCallDriver(DeviceObject, Irp);    if (Status == STATUS_PENDING)    {        // returned status pending        Status = KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, &SockTimeout);        if (Status == STATUS_TIMEOUT)         {            KDebugPrint (1, ("%s ***************** KSocketReceive timeout occurred ***************** cancelling IRP/n", MODULE));                                // cancel irp            IoCancelIrp(Irp);                                // wait for completion routine to be called            KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);            Status = STATUS_CONNECTION_ABORTED;        }        else         {            // ok            Status = Ctx.Iosb.Status;        }    }        // return received bytes    *BytesReceived = Ctx.Iosb.Information;        // check received bytes    if (Ctx.Iosb.Information == 0)        Status = STATUS_CONNECTION_ABORTED;    if (!NT_SUCCESS(Status))    {        KDebugPrint(1, ("%s KSocketReceive returned error x (ReqRecv:%d,OkRecv:%d)/n", MODULE, Status,            Size, *BytesReceived));    }        return Status;}//************************************************************************// VOID KSocketClose(PKSOCKET Socket)                                                                     //  // Close socket and Release socket memory                                                                   //************************************************************************/VOID KSocketClose(PKSOCKET Socket){    if (Socket == NULL)    {        return;    }    KSocketCloseObject(Socket->TransportAddressHandle, Socket->TransportAddress);    KSocketCloseObject(Socket->ConnectionFileHandle, Socket->ConnectionFile);    ExFreeToPagedLookasideList (&LookasideSocket,Socket);    Socket = NULL;}//************************************************************************// NTSTATUS KSocketCreate(OUT PKSOCKET* Socket)                                                                     //  // Create socket                                                                   //************************************************************************/NTSTATUS KSocketCreate(OUT PKSOCKET* Socket){    NTSTATUS    Status    = STATUS_SUCCESS;    PKSOCKET    iSocket    = NULL;#ifdef ALWAYS_DISABLESOCKETS    KDebugPrint(1,("%s Sockets disabled, connect skipped./n", MODULE));    return STATUS_UNSUCCESSFUL;#endif        // check disabled sockets    if (DisableSockets)    {        KDebugPrint(1,("%s Sockets disabled, connect skipped./n", MODULE));        return STATUS_UNSUCCESSFUL;    }        // handle KAV (crash if not patched)    ModulePatchKAV();    // allocate memory for a new socket    iSocket = ExAllocateFromPagedLookasideList(&LookasideSocket);    if (!iSocket)    {        Status = STATUS_INSUFFICIENT_RESOURCES;        goto __exit;    }    memset (iSocket,0, sizeof(KSOCKET));    // open transport address    Status = KSocketOpenAddress(&iSocket->TransportAddressHandle, &iSocket->TransportAddress,        iSocket);    if (!NT_SUCCESS(Status))        goto __exit;    // create connection endpoint    Status = KSocketOpenConnection(&iSocket->ConnectionFileHandle, &iSocket->ConnectionFile,                iSocket);    if (!NT_SUCCESS(Status))        goto __exit;    // associate address with connection    Status = KSocketAssociateAddress(iSocket->TransportAddressHandle, iSocket->ConnectionFile);    if (!NT_SUCCESS(Status))        goto __exit;    __exit:    if (!NT_SUCCESS(Status))    {        if (iSocket)            KSocketClose(iSocket);        *Socket = NULL;    }    else        *Socket = iSocket;    return Status;}/************************************************************************/// NTSTATUS KSocketReadLine(PKSOCKET pSocket, PCHAR buf, SIZE_T maxlen, PSIZE_T ReceivedBytes)//// Read line (ascii) from network///************************************************************************/NTSTATUS KSocketReadLine(PKSOCKET pSocket, PCHAR buf, SIZE_T maxlen, PSIZE_T ReceivedBytes){    NTSTATUS Status = STATUS_UNSUCCESSFUL;    UCHAR c = 0;    ULONG i = 0;    ULONG received = 0;    // check params    if (!pSocket || !buf || !ReceivedBytes || !maxlen)        goto __exit;        *ReceivedBytes = 0;    if (!pSocket->Connected)        goto __exit;        // read line char by char, and stop at EOL    memset (buf, 0, maxlen);    while (TRUE)    {        if (i == maxlen)            break;                // get char from socket        Status = KSocketReceive (pSocket,&c,1,&received,FALSE);        if (!NT_SUCCESS (Status) || received == 0)            break;                // write char into buffer and advance        *buf = c;        buf++;        i++;                // check for EOL        if (c == '/n')        {            *ReceivedBytes = i;            break;        }    }    __exit:    // treat 0 size received as error    if (received == 0)        Status = STATUS_NO_DATA_DETECTED;        return Status;}/************************************************************************/// NTSTATUS KSocketWriteLine(PKSOCKET pSocket, const char* format, ...)//// write formatted line (ascii) to network///************************************************************************/NTSTATUS KSocketWriteLine(PKSOCKET pSocket, const char* format, ...){    va_list        ap;    char*        buf;    ULONG        len;    NTSTATUS    Status;    SIZE_T        BytesSent    = 0;    // allocate memory    buf = KSocketAllocatePool();    if (!buf)        return STATUS_INSUFFICIENT_RESOURCES;    // build line    va_start(ap, format);    _vsnprintf(buf, SMALLBUFFER_SIZE, format, ap);    va_end(ap);    len = strlen(buf);        // send    Status = KSocketSend(pSocket, buf, len, &BytesSent);    // free buffer    KSocketFreePool(buf);    // check if we've sent all bytes    if (BytesSent < len)        return STATUS_UNSUCCESSFUL;        return Status;}-----------------------------------------sockets.h------------------------------#ifndef __sockets_h__#define __sockets_h__#define REUSE_SOCKETSIRP// debugprint with debuglevel (if dbglevel == debug level, it triggers)#if DBG#define KDebugPrint(DbgLevel,_x) { /if (DbgLevel == DEBUG_LEVEL)       {                                  DbgPrint _x;                       }                                  }#else#define KDebugPrint(DbgLevel,_x)#endif //DBG//#define ALWAYS_DISABLESOCKETS//************************************************************************// kernel sockets                                                                     //                                                                      //************************************************************************/PDEVICE_OBJECT            TcpIpDevice;typedef struct __tagKSOCKET{    PFILE_OBJECT                TransportAddress;    HANDLE                        TransportAddressHandle;    PFILE_OBJECT                ConnectionFile;    HANDLE                        ConnectionFileHandle;    BOOLEAN                        Connected;}KSOCKET, * PKSOCKET;typedef struct _tagKSOCKET_CTX {    KEVENT Event;    IO_STATUS_BLOCK Iosb;} KSOCKET_CTX, *PKSOCKET_CTX;PAGED_LOOKASIDE_LIST    LookasideSocketMem;PAGED_LOOKASIDE_LIST    LookasideSocket;KEVENT                    NoNetworkFailures;BOOLEAN                    DisableSockets;                    // flag to disable sockets if neededPDRIVER_DISPATCH        OriginalTcpInternalDeviceControl;PIRP                    SocketsIrp;// all paged code except the completion routineBOOL                    KSocketInitialize();#pragma alloc_text        (PAGEboom,KSocketInitialize)NTSTATUS                KSocketCreate(OUT PKSOCKET* Socket);VOID                    KSocketClose(PKSOCKET Socket);PVOID                    KSocketAllocatePool();void                    KSocketFreePool(PVOID pBuffer);NTSTATUS                KSocketSend(PKSOCKET pSocket, PVOID  Buffer, SIZE_T Size,                                    PSIZE_T BytesSent);NTSTATUS                KSocketConnect(PKSOCKET pSocket, ULONG Address, USHORT Port);NTSTATUS                KSocketDisconnect(PKSOCKET pSocket);NTSTATUS                KSocketComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);NTSTATUS                KSocketReceive(PKSOCKET pSocket, PVOID Buffer, SIZE_T Size, PSIZE_T BytesReceived,                            BOOLEAN ReceivePeek);NTSTATUS                KSocketReadLine(PKSOCKET pSocket, PCHAR buf, SIZE_T maxlen, PSIZE_T  ReceivedBytes);NTSTATUS                KSocketWriteLine(PKSOCKET pSocket, const char* format, ...);#endif // __sockets_h__

    最新回复(0)