From 87a61a625a1036f62407ebb8b4190daab3fd2e62 Mon Sep 17 00:00:00 2001 From: nganhkhoa Date: Tue, 25 Feb 2020 01:33:42 +0700 Subject: [PATCH] Add DeviceIo routine Add a simple device io routine to print routine code Fix variables due to recent Windows update to 19569 --- KMDF Driver2/Driver.cpp | 73 +++- KMDF Driver2/KMDF Driver2.vcxproj | 11 +- KMDF Driver2/KMDF Driver2.vcxproj.filters | 10 +- KMDF Driver2/simplewsk.c | 479 ++++++++++++++++++++++ KMDF Driver2/simplewsk.h | 55 +++ 5 files changed, 607 insertions(+), 21 deletions(-) create mode 100644 KMDF Driver2/simplewsk.c create mode 100644 KMDF Driver2/simplewsk.h diff --git a/KMDF Driver2/Driver.cpp b/KMDF Driver2/Driver.cpp index 16f75cb..b7d9a85 100644 --- a/KMDF Driver2/Driver.cpp +++ b/KMDF Driver2/Driver.cpp @@ -5,10 +5,12 @@ #include "sioctl.h" #include "Driver.h" -// #include "peformat.h" +#include "simplewsk.h" extern "C" DRIVER_INITIALIZE DriverEntry; extern "C" DRIVER_UNLOAD UnloadRoutine; +extern "C" DRIVER_DISPATCH DriverCreateClose; +extern "C" DRIVER_DISPATCH DriverControl; // extern "C" PDBGKD_GET_VERSION64 FindKdVersionBlock(void); #define NT_DEVICE_NAME L"\\Device\\poolscanner" @@ -35,6 +37,49 @@ ULONG64 lastVaOffset = 0; ULONG64 largePageTableOffset = 0; ULONG64 largePageSizeOffset = 0; +NTSTATUS +DriverCreateClose(PDEVICE_OBJECT /* DriverObject */, PIRP Irp) { + PAGED_CODE(); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +NTSTATUS +DriverControl(PDEVICE_OBJECT /* DriverObject */, PIRP Irp) { + PIO_STACK_LOCATION irpSp; + NTSTATUS ntStatus = STATUS_SUCCESS; + // ULONG inBufLength; + // ULONG outBufLength; + ULONG controlCode; + // PCHAR inBuf; + // PCHAR outBuf; + + PAGED_CODE(); + + irpSp = IoGetCurrentIrpStackLocation(Irp); + /* + * struct { + * ULONG OutputBufferLength; + * ULONG POINTER_ALIGNMENT InputBufferLength; + * ULONG POINTER_ALIGNMENT IoControlCode; + * PVOID Type3InputBuffer; + * } DeviceIoControl; + **/ + controlCode = irpSp->Parameters.DeviceIoControl.IoControlCode; + + DbgPrint("[NAK] :: [ ] Control Code : %lu\n", controlCode); + + + Irp->IoStatus.Status = ntStatus; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return ntStatus; +} + NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, @@ -47,7 +92,6 @@ DriverEntry( UNICODE_STRING ntWin32NameString; PDEVICE_OBJECT deviceObject = nullptr; - DriverObject->DriverUnload = UnloadRoutine; RtlInitUnicodeString(&ntUnicodeString, NT_DEVICE_NAME); returnStatus = IoCreateDevice( DriverObject, // Our Driver Object @@ -62,7 +106,10 @@ DriverEntry( return returnStatus; } - DbgPrint("[NAK] :: [+] Setup completed, GO GO GO !!!!\n"); + DriverObject->DriverUnload = UnloadRoutine; + DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverCreateClose; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverCreateClose; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverControl; RtlInitUnicodeString(&ntWin32NameString, DOS_DEVICE_NAME); returnStatus = IoCreateSymbolicLink(&ntWin32NameString, &ntUnicodeString); @@ -71,6 +118,8 @@ DriverEntry( IoDeleteDevice(deviceObject); } + DbgPrint("[NAK] :: [+] Setup completed, GO GO GO !!!!\n"); + OSVERSIONINFOW windowsVersionInfo; RtlGetVersion(&windowsVersionInfo); DbgPrint("[NAK] :: [ ] Windows version : %lu.%lu.%lu\n", @@ -104,14 +153,14 @@ DriverEntry( eprocessNameOffset = 0x5a8; eprocessLinkOffset = 0x448; listBLinkOffset = 0x8; - processHeadOffset = 0xc1f970; - miStateOffset = 0xc4f200; + processHeadOffset = 0xc1f960; + miStateOffset = 0xc4f040; hardwareOffset = 0x1580; systemNodeOffset = 0x20; firstVaOffset = 0x60; lastVaOffset = 0x68; - largePageTableOffset = 0xc17ed8; - largePageSizeOffset = 0xc17ed0; + largePageTableOffset = 0xc1a740; + largePageSizeOffset = 0xc1a738; } if (windowsVersionByPool == WINDOWS_NOT_SUPPORTED) { @@ -145,7 +194,8 @@ DriverEntry( // TODO: Exception????? PVOID eprocess = (PVOID)IoGetCurrentProcess(); - DbgPrint("[NAK] :: [ ] System eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + eprocessNameOffset)); + DbgPrint("[NAK] :: [ ] System eprocess : 0x%p, [%15s]\n", + eprocess, (char*)((ULONG64)eprocess + eprocessNameOffset)); PVOID processHead = (PVOID)(*(ULONG64*)((ULONG64)eprocess + eprocessLinkOffset + listBLinkOffset)); DbgPrint("[NAK] :: [ ] PsActiveProcessHead : 0x%p\n", processHead); PVOID ntosbase = (PVOID)((ULONG64)processHead - processHeadOffset); @@ -154,7 +204,8 @@ DriverEntry( DbgPrint("[NAK] :: [ ] Scan the PsActiveProcessHead linked-list\n"); while (*(ULONG64*)((ULONG64)eprocess + eprocessLinkOffset) != (ULONG64)processHead) { eprocess = (PVOID)(*(ULONG64*)((ULONG64)eprocess + eprocessLinkOffset) - eprocessLinkOffset); - DbgPrint("[NAK] :: [ ] eprocess : 0x%p, [%15s]\n", eprocess, (char*)((ULONG64)eprocess + eprocessNameOffset)); + DbgPrint("[NAK] :: [ ] eprocess : 0x%p, [%15s]\n", + eprocess, (char*)((ULONG64)eprocess + eprocessNameOffset)); } // TODO: Check if ntosbase is a PE, and the name is ntoskrnl.exe @@ -231,8 +282,8 @@ DriverEntry( DbgPrint("[NAK] :: [+] large page address : 0x%p\n", largePageTableArray); DbgPrint("[NAK] :: [+] large page size : 0x%llx\n", largePageTableSize); - scanNormalPool(nonPagedPoolStart, nonPagedPoolEnd); - scanLargePool(largePageTableArray, largePageTableSize); + // scanNormalPool(nonPagedPoolStart, nonPagedPoolEnd); + // scanLargePool(largePageTableArray, largePageTableSize); return returnStatus; } diff --git a/KMDF Driver2/KMDF Driver2.vcxproj b/KMDF Driver2/KMDF Driver2.vcxproj index 6c40e05..c4a6b2f 100644 --- a/KMDF Driver2/KMDF Driver2.vcxproj +++ b/KMDF Driver2/KMDF Driver2.vcxproj @@ -141,6 +141,11 @@ DbgengKernelDebugger + + + $(DDK_LIB_PATH)\netio.lib;%(AdditionalDependencies) + + @@ -149,15 +154,13 @@ + - + - - - diff --git a/KMDF Driver2/KMDF Driver2.vcxproj.filters b/KMDF Driver2/KMDF Driver2.vcxproj.filters index a484801..66b7041 100644 --- a/KMDF Driver2/KMDF Driver2.vcxproj.filters +++ b/KMDF Driver2/KMDF Driver2.vcxproj.filters @@ -27,6 +27,9 @@ Source Files + + Source Files + @@ -35,13 +38,8 @@ Header Files - + Header Files - - - Source Files - - \ No newline at end of file diff --git a/KMDF Driver2/simplewsk.c b/KMDF Driver2/simplewsk.c new file mode 100644 index 0000000..881790d --- /dev/null +++ b/KMDF Driver2/simplewsk.c @@ -0,0 +1,479 @@ +/*++ + +Module Name: + + simplewsk.c + +Abstract: + + Wrapper library for WSK functions + +Author: + + MaD, 12-May-2009 + +--*/ + +#include "simplewsk.h" + +static WSK_REGISTRATION g_WskRegistration; +static WSK_PROVIDER_NPI g_WskProvider; +static WSK_CLIENT_DISPATCH g_WskDispatch = {MAKE_WSK_VERSION(1, 0), 0, NULL}; + +enum { DEINITIALIZED, DEINITIALIZING, INITIALIZING, INITIALIZED }; + +static LONG g_SocketsState = DEINITIALIZED; + +static NTSTATUS NTAPI CompletionRoutine(__in PDEVICE_OBJECT DeviceObject, + __in PIRP Irp, + __in PKEVENT CompletionEvent) { + ASSERT(CompletionEvent); + + UNREFERENCED_PARAMETER(Irp); + UNREFERENCED_PARAMETER(DeviceObject); + + KeSetEvent(CompletionEvent, IO_NO_INCREMENT, FALSE); + return STATUS_MORE_PROCESSING_REQUIRED; +} + +static NTSTATUS InitWskData(__out PIRP* pIrp, __out PKEVENT CompletionEvent) { + ASSERT(pIrp); + ASSERT(CompletionEvent); + + *pIrp = IoAllocateIrp(1, FALSE); + if (!*pIrp) { + KdPrint(("InitWskData(): IoAllocateIrp() failed\n")); + return STATUS_INSUFFICIENT_RESOURCES; + } + + KeInitializeEvent(CompletionEvent, SynchronizationEvent, FALSE); + IoSetCompletionRoutine(*pIrp, CompletionRoutine, CompletionEvent, TRUE, TRUE, + TRUE); + return STATUS_SUCCESS; +} + +static NTSTATUS InitWskBuffer(__in PVOID Buffer, __in ULONG BufferSize, + __out PWSK_BUF WskBuffer) { + NTSTATUS Status = STATUS_SUCCESS; + + ASSERT(Buffer); + ASSERT(BufferSize); + ASSERT(WskBuffer); + + WskBuffer->Offset = 0; + WskBuffer->Length = BufferSize; + + WskBuffer->Mdl = IoAllocateMdl(Buffer, BufferSize, FALSE, FALSE, NULL); + if (!WskBuffer->Mdl) { + KdPrint(("InitWskBuffer(): IoAllocateMdl() failed\n")); + return STATUS_INSUFFICIENT_RESOURCES; + } + + __try { + MmProbeAndLockPages(WskBuffer->Mdl, KernelMode, IoWriteAccess); + } __except (EXCEPTION_EXECUTE_HANDLER) { + KdPrint(("InitWskBuffer(): MmProbeAndLockPages(%p) failed\n", Buffer)); + IoFreeMdl(WskBuffer->Mdl); + Status = STATUS_ACCESS_VIOLATION; + } + + return Status; +} + +static VOID FreeWskBuffer(__in PWSK_BUF WskBuffer) { + ASSERT(WskBuffer); + + MmUnlockPages(WskBuffer->Mdl); + IoFreeMdl(WskBuffer->Mdl); +} + +// +// Library initialization routine +// + +NTSTATUS NTAPI WSKStartup() { + WSK_CLIENT_NPI WskClient = {0}; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + if (InterlockedCompareExchange(&g_SocketsState, INITIALIZING, + DEINITIALIZED) != DEINITIALIZED) + return STATUS_ALREADY_REGISTERED; + + WskClient.ClientContext = NULL; + WskClient.Dispatch = &g_WskDispatch; + + Status = WskRegister(&WskClient, &g_WskRegistration); + if (!NT_SUCCESS(Status)) { + KdPrint(("WskRegister() failed with status 0x%08X\n", Status)); + InterlockedExchange(&g_SocketsState, DEINITIALIZED); + return Status; + } + + Status = + WskCaptureProviderNPI(&g_WskRegistration, WSK_NO_WAIT, &g_WskProvider); + if (!NT_SUCCESS(Status)) { + KdPrint(("WskCaptureProviderNPI() failed with status 0x%08X\n", Status)); + WskDeregister(&g_WskRegistration); + InterlockedExchange(&g_SocketsState, DEINITIALIZED); + return Status; + } + + InterlockedExchange(&g_SocketsState, INITIALIZED); + return STATUS_SUCCESS; +} + +// +// Library deinitialization routine +// + +VOID NTAPI WSKCleanup() { + if (InterlockedCompareExchange(&g_SocketsState, INITIALIZED, + DEINITIALIZING) != INITIALIZED) + return; + + WskReleaseProviderNPI(&g_WskRegistration); + WskDeregister(&g_WskRegistration); + + InterlockedExchange(&g_SocketsState, DEINITIALIZED); +} + +PWSK_SOCKET +NTAPI +CreateSocket(__in ADDRESS_FAMILY AddressFamily, __in USHORT SocketType, + __in ULONG Protocol, __in ULONG Flags) { + KEVENT CompletionEvent = {0}; + PIRP Irp = NULL; + PWSK_SOCKET WskSocket = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + if (g_SocketsState != INITIALIZED) return NULL; + + Status = InitWskData(&Irp, &CompletionEvent); + if (!NT_SUCCESS(Status)) { + KdPrint( + ("CreateSocket(): InitWskData() failed with status 0x%08X\n", Status)); + return NULL; + } + + Status = g_WskProvider.Dispatch->WskSocket( + g_WskProvider.Client, AddressFamily, SocketType, Protocol, Flags, NULL, + NULL, NULL, NULL, NULL, Irp); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + WskSocket = + NT_SUCCESS(Status) ? (PWSK_SOCKET)Irp->IoStatus.Information : NULL; + + IoFreeIrp(Irp); + return (PWSK_SOCKET)WskSocket; +} + +NTSTATUS +NTAPI +CloseSocket(__in PWSK_SOCKET WskSocket) { + KEVENT CompletionEvent = {0}; + PIRP Irp = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + if (g_SocketsState != INITIALIZED || !WskSocket) + return STATUS_INVALID_PARAMETER; + + Status = InitWskData(&Irp, &CompletionEvent); + if (!NT_SUCCESS(Status)) { + KdPrint( + ("CloseSocket(): InitWskData() failed with status 0x%08X\n", Status)); + return Status; + } + + Status = ((PWSK_PROVIDER_BASIC_DISPATCH)WskSocket->Dispatch) + ->WskCloseSocket(WskSocket, Irp); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + IoFreeIrp(Irp); + return Status; +} + +NTSTATUS +NTAPI +Connect(__in PWSK_SOCKET WskSocket, __in PSOCKADDR RemoteAddress) { + KEVENT CompletionEvent = {0}; + PIRP Irp = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + if (g_SocketsState != INITIALIZED || !WskSocket || !RemoteAddress) + return STATUS_INVALID_PARAMETER; + + Status = InitWskData(&Irp, &CompletionEvent); + if (!NT_SUCCESS(Status)) { + KdPrint(("Connect(): InitWskData() failed with status 0x%08X\n", Status)); + return Status; + } + + Status = ((PWSK_PROVIDER_CONNECTION_DISPATCH)WskSocket->Dispatch) + ->WskConnect(WskSocket, RemoteAddress, 0, Irp); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + IoFreeIrp(Irp); + return Status; +} + +PWSK_SOCKET +NTAPI +SocketConnect(__in USHORT SocketType, __in ULONG Protocol, + __in PSOCKADDR RemoteAddress, __in PSOCKADDR LocalAddress) { + KEVENT CompletionEvent = {0}; + PIRP Irp = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + PWSK_SOCKET WskSocket = NULL; + + if (g_SocketsState != INITIALIZED || !RemoteAddress || !LocalAddress) + return NULL; + + Status = InitWskData(&Irp, &CompletionEvent); + if (!NT_SUCCESS(Status)) { + KdPrint(("InitWskData() failed with status 0x%08X\n", Status)); + return NULL; + } + + Status = g_WskProvider.Dispatch->WskSocketConnect( + g_WskProvider.Client, SocketType, Protocol, LocalAddress, RemoteAddress, + 0, NULL, NULL, NULL, NULL, NULL, Irp); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + WskSocket = + NT_SUCCESS(Status) ? (PWSK_SOCKET)Irp->IoStatus.Information : NULL; + + IoFreeIrp(Irp); + return WskSocket; +} + +LONG NTAPI Send(__in PWSK_SOCKET WskSocket, __in PVOID Buffer, + __in ULONG BufferSize, __in ULONG Flags) { + KEVENT CompletionEvent = {0}; + PIRP Irp = NULL; + WSK_BUF WskBuffer = {0}; + LONG BytesSent = SOCKET_ERROR; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + if (g_SocketsState != INITIALIZED || !WskSocket || !Buffer || !BufferSize) + return SOCKET_ERROR; + + Status = InitWskBuffer(Buffer, BufferSize, &WskBuffer); + if (!NT_SUCCESS(Status)) { + KdPrint(("Send(): InitWskData() failed with status 0x%08X\n", Status)); + return SOCKET_ERROR; + } + + Status = InitWskData(&Irp, &CompletionEvent); + if (!NT_SUCCESS(Status)) { + KdPrint(("Send(): InitWskData() failed with status 0x%08X\n", Status)); + FreeWskBuffer(&WskBuffer); + return SOCKET_ERROR; + } + + Status = ((PWSK_PROVIDER_CONNECTION_DISPATCH)WskSocket->Dispatch) + ->WskSend(WskSocket, &WskBuffer, Flags, Irp); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + BytesSent = + NT_SUCCESS(Status) ? (LONG)Irp->IoStatus.Information : SOCKET_ERROR; + + IoFreeIrp(Irp); + FreeWskBuffer(&WskBuffer); + return BytesSent; +} + +LONG NTAPI SendTo(__in PWSK_SOCKET WskSocket, __in PVOID Buffer, + __in ULONG BufferSize, __in_opt PSOCKADDR RemoteAddress) { + KEVENT CompletionEvent = {0}; + PIRP Irp = NULL; + WSK_BUF WskBuffer = {0}; + LONG BytesSent = SOCKET_ERROR; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + if (g_SocketsState != INITIALIZED || !WskSocket || !Buffer || !BufferSize) + return SOCKET_ERROR; + + Status = InitWskBuffer(Buffer, BufferSize, &WskBuffer); + if (!NT_SUCCESS(Status)) { + KdPrint(("SendTo(): InitWskData() failed with status 0x%08X\n", Status)); + return SOCKET_ERROR; + } + + Status = InitWskData(&Irp, &CompletionEvent); + if (!NT_SUCCESS(Status)) { + KdPrint(("SendTo(): InitWskData() failed with status 0x%08X\n", Status)); + FreeWskBuffer(&WskBuffer); + return SOCKET_ERROR; + } + + Status = + ((PWSK_PROVIDER_DATAGRAM_DISPATCH)WskSocket->Dispatch) + ->WskSendTo(WskSocket, &WskBuffer, 0, RemoteAddress, 0, NULL, Irp); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + BytesSent = + NT_SUCCESS(Status) ? (LONG)Irp->IoStatus.Information : SOCKET_ERROR; + + IoFreeIrp(Irp); + FreeWskBuffer(&WskBuffer); + return BytesSent; +} + +LONG NTAPI Receive(__in PWSK_SOCKET WskSocket, __out PVOID Buffer, + __in ULONG BufferSize, __in ULONG Flags) { + KEVENT CompletionEvent = {0}; + PIRP Irp = NULL; + WSK_BUF WskBuffer = {0}; + LONG BytesReceived = SOCKET_ERROR; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + if (g_SocketsState != INITIALIZED || !WskSocket || !Buffer || !BufferSize) + return SOCKET_ERROR; + + Status = InitWskBuffer(Buffer, BufferSize, &WskBuffer); + if (!NT_SUCCESS(Status)) { + KdPrint(("Receive(): InitWskData() failed with status 0x%08X\n", Status)); + return SOCKET_ERROR; + } + + Status = InitWskData(&Irp, &CompletionEvent); + if (!NT_SUCCESS(Status)) { + KdPrint(("Receive(): InitWskData() failed with status 0x%08X\n", Status)); + FreeWskBuffer(&WskBuffer); + return SOCKET_ERROR; + } + + Status = ((PWSK_PROVIDER_CONNECTION_DISPATCH)WskSocket->Dispatch) + ->WskReceive(WskSocket, &WskBuffer, Flags, Irp); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + BytesReceived = + NT_SUCCESS(Status) ? (LONG)Irp->IoStatus.Information : SOCKET_ERROR; + + IoFreeIrp(Irp); + FreeWskBuffer(&WskBuffer); + return BytesReceived; +} + +LONG NTAPI ReceiveFrom(__in PWSK_SOCKET WskSocket, __out PVOID Buffer, + __in ULONG BufferSize, __out_opt PSOCKADDR RemoteAddress, + __out_opt PULONG ControlFlags) { + KEVENT CompletionEvent = {0}; + PIRP Irp = NULL; + WSK_BUF WskBuffer = {0}; + LONG BytesReceived = SOCKET_ERROR; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + if (g_SocketsState != INITIALIZED || !WskSocket || !Buffer || !BufferSize) + return SOCKET_ERROR; + + Status = InitWskBuffer(Buffer, BufferSize, &WskBuffer); + if (!NT_SUCCESS(Status)) { + KdPrint( + ("ReceiveFrom(): InitWskData() failed with status 0x%08X\n", Status)); + return SOCKET_ERROR; + } + + Status = InitWskData(&Irp, &CompletionEvent); + if (!NT_SUCCESS(Status)) { + KdPrint( + ("ReceiveFrom(): InitWskData() failed with status 0x%08X\n", Status)); + FreeWskBuffer(&WskBuffer); + return SOCKET_ERROR; + } + + Status = ((PWSK_PROVIDER_DATAGRAM_DISPATCH)WskSocket->Dispatch) + ->WskReceiveFrom(WskSocket, &WskBuffer, 0, RemoteAddress, 0, + NULL, ControlFlags, Irp); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + BytesReceived = + NT_SUCCESS(Status) ? (LONG)Irp->IoStatus.Information : SOCKET_ERROR; + + IoFreeIrp(Irp); + FreeWskBuffer(&WskBuffer); + return BytesReceived; +} + +NTSTATUS +NTAPI +Bind(__in PWSK_SOCKET WskSocket, __in PSOCKADDR LocalAddress) { + KEVENT CompletionEvent = {0}; + PIRP Irp = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + if (g_SocketsState != INITIALIZED || !WskSocket || !LocalAddress) + return STATUS_INVALID_PARAMETER; + + Status = InitWskData(&Irp, &CompletionEvent); + if (!NT_SUCCESS(Status)) { + KdPrint(("Bind(): InitWskData() failed with status 0x%08X\n", Status)); + return Status; + } + + Status = ((PWSK_PROVIDER_CONNECTION_DISPATCH)WskSocket->Dispatch) + ->WskBind(WskSocket, LocalAddress, 0, Irp); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + IoFreeIrp(Irp); + return Status; +} + +PWSK_SOCKET +NTAPI +Accept(__in PWSK_SOCKET WskSocket, __out_opt PSOCKADDR LocalAddress, + __out_opt PSOCKADDR RemoteAddress) { + KEVENT CompletionEvent = {0}; + PIRP Irp = NULL; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + PWSK_SOCKET AcceptedSocket = NULL; + + if (g_SocketsState != INITIALIZED || !WskSocket) return NULL; + + Status = InitWskData(&Irp, &CompletionEvent); + if (!NT_SUCCESS(Status)) { + KdPrint(("Accept(): InitWskData() failed with status 0x%08X\n", Status)); + return NULL; + } + + Status = ((PWSK_PROVIDER_LISTEN_DISPATCH)WskSocket->Dispatch) + ->WskAccept(WskSocket, 0, NULL, NULL, LocalAddress, + RemoteAddress, Irp); + if (Status == STATUS_PENDING) { + KeWaitForSingleObject(&CompletionEvent, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + + AcceptedSocket = + NT_SUCCESS(Status) ? (PWSK_SOCKET)Irp->IoStatus.Information : NULL; + + IoFreeIrp(Irp); + return AcceptedSocket; +} diff --git a/KMDF Driver2/simplewsk.h b/KMDF Driver2/simplewsk.h new file mode 100644 index 0000000..d776e72 --- /dev/null +++ b/KMDF Driver2/simplewsk.h @@ -0,0 +1,55 @@ + +#pragma warning(push) +#pragma warning(disable : 4201) // nameless struct/union +#pragma warning(disable : 4214) // bit field types other than int + +#pragma once +#include +#include + +#pragma warning(pop) + +#define SOCKET_ERROR -1 + +NTSTATUS NTAPI WSKStartup(); +VOID NTAPI WSKCleanup(); + +PWSK_SOCKET +NTAPI +CreateSocket(__in ADDRESS_FAMILY AddressFamily, __in USHORT SocketType, + __in ULONG Protocol, __in ULONG Flags); + +NTSTATUS +NTAPI +CloseSocket(__in PWSK_SOCKET WskSocket); + +NTSTATUS +NTAPI +Connect(__in PWSK_SOCKET WskSocket, __in PSOCKADDR RemoteAddress); + +PWSK_SOCKET +NTAPI +SocketConnect(__in USHORT SocketType, __in ULONG Protocol, + __in PSOCKADDR RemoteAddress, __in PSOCKADDR LocalAddress); + +LONG NTAPI Send(__in PWSK_SOCKET WskSocket, __in PVOID Buffer, + __in ULONG BufferSize, __in ULONG Flags); + +LONG NTAPI SendTo(__in PWSK_SOCKET WskSocket, __in PVOID Buffer, + __in ULONG BufferSize, __in_opt PSOCKADDR RemoteAddress); + +LONG NTAPI Receive(__in PWSK_SOCKET WskSocket, __out PVOID Buffer, + __in ULONG BufferSize, __in ULONG Flags); + +LONG NTAPI ReceiveFrom(__in PWSK_SOCKET WskSocket, __out PVOID Buffer, + __in ULONG BufferSize, __out_opt PSOCKADDR RemoteAddress, + __out_opt PULONG ControlFlags); + +NTSTATUS +NTAPI +Bind(__in PWSK_SOCKET WskSocket, __in PSOCKADDR LocalAddress); + +PWSK_SOCKET +NTAPI +Accept(__in PWSK_SOCKET WskSocket, __out_opt PSOCKADDR LocalAddress, + __out_opt PSOCKADDR RemoteAddress);