Kernel mode sockets library for the masses[zt]

Kernel mode sockets library for the masses
By: valerino

Kernel mode sockets library

It'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 Christ
i'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 can
bypass 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 more
from 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 %08x (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 %08x (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 needed
PDRIVER_DISPATCH        OriginalTcpInternalDeviceControl;
PIRP                    SocketsIrp;

// all paged code except the completion routine
BOOL                    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 library

It'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 Christ
i'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 can
bypass 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 more
from 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 %08x (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 %08x (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 needed
PDRIVER_DISPATCH        OriginalTcpInternalDeviceControl;
PIRP                    SocketsIrp;

// all paged code except the completion routine
BOOL                    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__
内容概要:本文研究了基于CNN-BiGRU-Attention混合神经网络模型的风电功率预测方法,旨在提升风力发电功率预测的准确性。该模型融合卷积神经网络(CNN)以提取输入变量中的局部时空特征,结合双向门控循环单元(BiGRU)充分捕捉时间序列前后向的长期依赖关系,并引入注意力机制(Attention)动态加权关键时间步的特征信息,增强模型对重要时刻的敏感度。研究采用多变量输入进行单步预测,综合纳入风速、风向、温度等多种气象因素作为模型输入,全面反映环境变量对风电输出的影响。通过Matlab平台完成模型构建、训练与仿真验证,实验结果表明该混合模型在预测精度与稳定性方面优于传统单一模型,有效提升了风电功率预测性能。; 适合人群:具备一定机器学习与深度学习理论基础,熟悉Matlab编程环境,从事新能源发电预测、电力系统调度、智能算法应用等相关领域的科研人员、工程技术人员及高校研究生。; 使用场景及目标:①应用于风电场实际运行中的短期功率预测,提高电网调度的安全性与可再生能源消纳效率;②为深度学习模型在复杂时序预测任务中的设计与优化提供实践范例,推动AI技术在能源系统智能化中的深度融合;③支持学术研究复现、课程项目设计与教学演示,帮助深入理解CNN、BiGRU与Attention机制的协同建模范式与实现细节。; 阅读建议:建议结合提供的Matlab代码进行动手实践,重点关注数据预处理流程、模型网络结构设计、超参数调优及训练收敛过程,鼓励尝试替换输入变量组合、调整网络层数或优化注意力结构,以进一步探究模型性能边界并提升预测鲁棒性。
内容概要:本文研究了基于Benders分解算法与输电网-配电网运营商(TSO-DSO)协调机制的双层优化模型,旨在有效应对新能源出力波动、负荷不确定性等对现代电力系统运行带来的挑战。模型上层由输电网运营商(TSO)负责全局资源优化与主网稳定性调控,下层由多个配电网运营商(DSO)实现本地分布式能源的灵活调度,通过Benders分解实现上下层之间的迭代协调与信息交互,从而在保障系统安全的前提下提升整体运行的经济性与鲁棒性。研究提供了完整的Matlab代码实现,涵盖数学建模、算法求解、收敛性分析及仿真结果可视化等环节,有助于深入理解双层优化架构在输配电网协同调度中的具体应用与技术细节。; 适合人群:具备电力系统分析、优化理论基础及一定Matlab编程能力的研究生、科研人员,以及从事电网调度、能源系统规划等相关领域的工程技术人员。; 使用场景及目标:①掌握Benders分解在电力系统双层优化问题中的建模与求解流程;②理解TSO-DSO协同机制下输配电网交互建模的核心思想与实现方法;③复现并拓展高水平学术论文中的优化模型,服务于科研项目攻关或实际工程仿真需求。; 阅读建议:建议结合凸优化理论、电力系统经济调度与Benders分解原理进行系统学习,优先运行并调试所提供的Matlab代码,调整关键参数以观察算法收敛行为与模型性能变化,从而深化对协调机制与优化机理的理解。
内容概要:本文档是一份关于经济学期刊论文复现的研究资料,聚焦核心议题“数字化转型能否促进企业的高质量发展”。文档构建了一个完整的量化分析框架,基于中国上市公司数据,实证探讨数字化转型对企业全要素生产率(TFP)及高质量发展的实际影响。内容涵盖数字化转型指标的构建、企业高质量发展评价体系的设计、计量经济模型的选择与应用(如固定效应模型、GMM方法),并提供Matlab代码实现全过程,包括数据处理、模型估计与稳健性检验。研究还系统梳理了OL、FE、LP、OP、GMM等多种全要素生产率的测算方法,为读者复现高水平经济学论文、深入理解数字经济时代的企业发展路径与政策含义提供了详尽的技术支持与理论指导。; 适合人群:具备扎实的经济学理论基础和较强的定量分析能力,熟悉Matlab或Python编程语言,正在从事经济管理、产业经济或数字经济等领域研究的研究生、高校教师及科研机构研究人员。; 使用场景及目标:①完整复现经济学顶刊论文的实证研究流程,掌握规范的学术研究范式;②学习并应用数字化转型与企业绩效间的因果识别策略,提升独立开展实证研究的能力;③为撰写学位论文、申报科研课题或编制政策咨询报告中涉及数字经济效应的章节提供直接的方法论参考和代码支持; 阅读建议:建议读者务必结合文档提供的数据与Matlab代码进行同步实操,重点钻研变量定义、模型设定、内生性处理和稳健性检验等关键环节,通过反复调试与验证,深刻领会高水平实证研究的严谨逻辑与技术细节,从而全面提升自身的科研素养与论文写作水平。
内容概要:本文围绕“绿电直连型电氢氨园区优化运行”开展创新性未发表研究,提出一种集成绿色电力直接供给、电解水制氢与合成氨工艺的多能耦合系统优化模型,旨在实现园区能源系统的低碳化、高效化与经济化运行。研究采用Matlab与Python编程语言,结合实际气象与负荷数据,构建涵盖电-氢-氨能量转换、存储与利用全过程的能量流、物质流及经济性协同优化框架,重点解决可再生能源出力波动导致的供需失衡问题,并通过优化电解槽、储氢罐、合成氨反应器等关键设备的运行策略与容量配置,提升系统对风光能源的就地消纳能力。文中配套提供完整的仿真代码、原始数据及Word格式论文,支持结果复现与模型拓展,具有较高的科研参考价值与工程应用潜力。; 适合人群:具备电力系统、能源工程、优化建模或新能源技术背景,从事综合能源系统、氢能利用、碳中和园区等相关领域研究的研发人员及硕士、博士研究生。; 使用场景及目标:①研究绿电直供模式下电-氢-氨多能系统协同运行机制与优化调度策略;②探索高比例可再生能源就地转化为高附加值化工产品的技术路径;③为工业园区实现深度脱碳与能源自洽提供决策支持;④作为学术论文撰写、课题申报或科研复现的高质量参考资料。; 阅读建议:建议结合Matlab与Python代码逐模块解析模型实现过程,重点关注目标函数构建、约束条件设定(如设备动态特性、能量平衡、安全边界)以及多场景仿真对比分析,宜在调试过程中调整权重系数与参数设置,深入理解系统灵敏度与优化机理,并尝试引入更多不确定性因素进行鲁棒性扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值