Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*++
- Copyright (c) 1999 - 2002 Microsoft Corporation
- Module Name:
- nullFilter.c
- Abstract:
- This is the main module of the nullFilter mini filter driver.
- It is a simple minifilter that registers itself with the main filter
- for no callback operations.
- Environment:
- Kernel mode
- --*/
- #include <fltKernel.h>
- #include <wdm.h>
- #include <dontuse.h>
- #include <stdio.h>
- #include <suppress.h>
- #include "policiessandbox.h"
- #pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")
- //---------------------------------------------------------------------------
- // Global variables
- //---------------------------------------------------------------------------
- #define NULL_FILTER_FILTER_NAME L"policiessandbox"
- typedef struct {
- PDRIVER_OBJECT pDriverObject;
- PFLT_FILTER fltHandle;
- ULONG state; // driver state (see DRIVER_STATE_* values)
- struct {
- PEPROCESS UserProcess; // user process that connected to the port
- PFLT_PORT ServerPort; // listens for incoming connections
- PFLT_PORT ClientPort; // client port for a connection to user-mode
- } Connection;
- struct {
- HANDLE CurrentProcessID;
- HANDLE CurrentThreadID;
- } procinfo;
- LONG volatile pcListCount; // number of processes (note it may be more than PID_NUMHASH)
- EX_PUSH_LOCK pcListLock;
- LIST_ENTRY cnList; // context-node list (PS_CONTEXT_NODE entries)
- EX_PUSH_LOCK cnListLock;
- } _DRIVER_DATA, *PDRIVER_DATA;
- _DRIVER_DATA DRIVER_DATA = {0};
- /*************************************************************************
- Prototypes for the startup and unload routines used for
- this Filter.
- Implementation in nullFilter.c
- *************************************************************************/
- DRIVER_INITIALIZE DriverEntry;
- NTSTATUS FLTAPI
- DriverEntry (
- __in PDRIVER_OBJECT DriverObject,
- __in PUNICODE_STRING RegistryPath
- );
- NTSTATUS FLTAPI
- PtFilterUnload (
- __in FLT_FILTER_UNLOAD_FLAGS Flags
- );
- NTSTATUS FLTAPI
- PtFilterTeardown (
- __in FLT_FILTER_UNLOAD_FLAGS Flags
- );
- NTSTATUS FLTAPI
- PtFilterQueryTeardown (
- __in PCFLT_RELATED_OBJECTS FltObjects,
- __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
- );
- //
- // Assign text sections for each routine.
- //
- #ifdef ALLOC_PRAGMA
- #pragma alloc_text(INIT, DriverEntry)
- #pragma alloc_text(PAGE, PtFilterUnload)
- #pragma alloc_text(PAGE, PtFilterTeardown)
- #pragma alloc_text(PAGE, PtInstanceSetup)
- #pragma alloc_text(PAGE, PtInstanceQueryTeardown)
- #pragma alloc_text(PAGE, PtInstanceTeardownStart)
- #pragma alloc_text(PAGE, PtInstanceTeardownComplete)
- #pragma alloc_text(PAGE, CommPortConnect)
- #pragma alloc_text(PAGE, CommPortDisconnect)
- #pragma alloc_text(PAGE, CommPortMessageNotify)
- #endif
- //
- // This defines what we want to filter with FltMgr
- //
- CONST FLT_REGISTRATION FilterRegistration = {
- sizeof( FLT_REGISTRATION ), // Size
- FLT_REGISTRATION_VERSION, // Version
- 0, // Flags
- NULL, // Context
- NULL, // Operation callbacks
- PtFilterUnload, // FilterUnload
- PtInstanceSetup, // InstanceSetup
- PtInstanceQueryTeardown, // InstanceQueryTeardown
- PtInstanceTeardownStart, // InstanceTeardownStart
- PtInstanceTeardownComplete, // InstanceTeardownComplete
- NULL, // GenerateFileName
- NULL, // GenerateDestinationFileName
- NULL // NormalizeNameComponent
- };
- /*************************************************************************
- Filter initialization and unload routines.
- *************************************************************************/
- /*++
- Routine Description:
- This is the initialization routine for this miniFilter driver. This
- registers the miniFilter with FltMgr and initializes all
- its global data structures.
- Arguments:
- DriverObject - Pointer to driver object created by the system to
- represent this driver.
- RegistryPath - Unicode string identifying where the parameters for this
- driver are located in the registry.
- Return Value:
- Returns STATUS_SUCCESS.
- --*/
- NTSTATUS FLTAPI
- DriverEntry (
- __in PDRIVER_OBJECT DriverObject,
- __in PUNICODE_STRING RegistryPath
- )
- {
- /* locals */
- NTSTATUS status;
- OBJECT_ATTRIBUTES attr;
- UNICODE_STRING portName;
- PSECURITY_DESCRIPTOR securityDescriptor;
- /* unused */
- UNREFERENCED_PARAMETER( RegistryPath );
- /* code */
- __try {
- // Init process contexts list
- FltInitializePushLock( &DRIVER_DATA.pcListLock );
- // Init context node list
- InitializeListHead( &DRIVER_DATA.cnList );
- FltInitializePushLock( &DRIVER_DATA.cnListLock );
- // Register filter
- status = FltRegisterFilter( DriverObject,
- &FilterRegistration,
- &DRIVER_DATA.fltHandle );
- // Setup security descriptor
- status = FltBuildDefaultSecurityDescriptor( &securityDescriptor, FLT_PORT_ALL_ACCESS );
- if ( !NT_SUCCESS( status )) __leave;
- RtlInitUnicodeString( &portName, PIPortName );
- InitializeObjectAttributes( &attr, &portName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, securityDescriptor );
- status = FltCreateCommunicationPort( DRIVER_DATA.fltHandle, &DRIVER_DATA.Connection.ServerPort, &attr, NULL, CommPortConnect, CommPortDisconnect, CommPortMessageNotify, 1 );
- // - free the security descriptor in all cases. It is not needed once the call to FltCreateCommunicationPort( ) is made.
- FltFreeSecurityDescriptor( securityDescriptor );
- if ( !NT_SUCCESS( status )) __leave;
- if (NT_SUCCESS( status )) {
- // Start filtering i/o
- status = FltStartFiltering( DRIVER_DATA.fltHandle );
- }
- ASSERT( NT_SUCCESS( status ) );
- } __finally {
- FltUnregisterFilter( DRIVER_DATA.fltHandle );
- FltCloseCommunicationPort( DRIVER_DATA.Connection.ServerPort );
- }
- return status;
- }
- /*++
- Routine Description:
- This is the unload routine for this miniFilter driver. This is called
- when the minifilter is about to be unloaded. We can fail this unload
- request if this is not a mandatory unloaded indicated by the Flags
- parameter.
- Arguments:
- Flags - Indicating if this is a mandatory unload.
- Return Value:
- Returns the final status of this operation.
- --*/
- NTSTATUS FLTAPI
- PtFilterUnload(
- __in FLT_FILTER_UNLOAD_FLAGS Flags
- )
- {
- UNREFERENCED_PARAMETER( Flags );
- PAGED_CODE();
- FltUnregisterFilter( DRIVER_DATA.fltHandle );
- FltCloseCommunicationPort( DRIVER_DATA.Connection.ServerPort );
- DbgPrint("PoliciesSandbox!PtFilterUnload: Entered\n");
- return STATUS_SUCCESS;
- }
- /*++
- Routine Description:
- This is the unload routine for this miniFilter driver. This is called
- when the minifilter is about to be unloaded. We can fail this unload
- request if this is not a mandatory unloaded indicated by the Flags
- parameter.
- Arguments:
- Flags - Indicating if this is a mandatory unload.
- Return Value:
- Returns the final status of this operation.
- --*/
- NTSTATUS FLTAPI
- PtFilterTeardown(
- __in FLT_FILTER_UNLOAD_FLAGS Flags
- )
- {
- UNREFERENCED_PARAMETER( Flags );
- PAGED_CODE();
- DbgPrint("PoliciesSandbox!PtFilterTeardown: Entered\n");
- return STATUS_SUCCESS;
- }
- /*++
- Routine Description:
- This routine is called whenever a new instance is created on a volume. This
- gives us a chance to decide if we need to attach to this volume or not.
- If this routine is not defined in the registration structure, automatic
- instances are alwasys created.
- Arguments:
- FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
- opaque handles to this filter, instance and its associated volume.
- Flags - Flags describing the reason for this attach request.
- Return Value:
- STATUS_SUCCESS - attach
- STATUS_FLT_DO_NOT_ATTACH - do not attach
- --*/
- NTSTATUS FLTAPI
- PtInstanceSetup (
- __in PCFLT_RELATED_OBJECTS FltObjects,
- __in FLT_INSTANCE_SETUP_FLAGS Flags,
- __in DEVICE_TYPE VolumeDeviceType,
- __in FLT_FILESYSTEM_TYPE VolumeFilesystemType
- )
- {
- UNREFERENCED_PARAMETER( FltObjects );
- UNREFERENCED_PARAMETER( Flags );
- UNREFERENCED_PARAMETER( VolumeDeviceType );
- UNREFERENCED_PARAMETER( VolumeFilesystemType );
- PAGED_CODE();
- DbgPrint("PoliciesSandbox!PtInstanceSetup: Entered\n");
- return STATUS_SUCCESS;
- }
- /*++
- Routine Description:
- This is the instance detach routine for this miniFilter driver.
- This is called when an instance is being manually deleted by a
- call to FltDetachVolume or FilterDetach thereby giving us a
- chance to fail that detach request.
- Arguments:
- FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
- opaque handles to this filter, instance and its associated volume.
- Flags - Indicating where this detach request came from.
- Return Value:
- Returns the status of this operation.
- --*/
- NTSTATUS FLTAPI
- PtInstanceQueryTeardown (
- __in PCFLT_RELATED_OBJECTS FltObjects,
- __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
- )
- {
- UNREFERENCED_PARAMETER( FltObjects );
- UNREFERENCED_PARAMETER( Flags );
- PAGED_CODE();
- DbgPrint("PoliciesSandbox!PtInstanceQueryTeardown: Entered\n");
- return STATUS_SUCCESS;
- }
- VOID FLTAPI
- PtInstanceTeardownStart (
- __in PCFLT_RELATED_OBJECTS FltObjects,
- __in FLT_INSTANCE_TEARDOWN_FLAGS Flags
- )
- /*++
- Routine Description:
- This routine is called at the start of instance teardown.
- Arguments:
- FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
- opaque handles to this filter, instance and its associated volume.
- Flags - Reason why this instance is been deleted.
- Return Value:
- None.
- --*/
- {
- UNREFERENCED_PARAMETER( FltObjects );
- UNREFERENCED_PARAMETER( Flags );
- PAGED_CODE();
- DbgPrint("PassThrough!PtInstanceTeardownStart: Entered\n");
- }
- VOID FLTAPI
- PtInstanceTeardownComplete (
- __in PCFLT_RELATED_OBJECTS FltObjects,
- __in FLT_INSTANCE_TEARDOWN_FLAGS Flags
- )
- /*++
- Routine Description:
- This routine is called at the end of instance teardown.
- Arguments:
- FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
- opaque handles to this filter, instance and its associated volume.
- Flags - Reason why this instance is been deleted.
- Return Value:
- None.
- --*/
- {
- UNREFERENCED_PARAMETER( FltObjects );
- UNREFERENCED_PARAMETER( Flags );
- PAGED_CODE();
- DbgPrint("PassThrough!PtInstanceTeardownComplete: Entered\n");
- }
- /*++
- Routine Description:
- This function is called when user-mode connects to the server port - to estabilish a
- connection.
- Arguments:
- InitializedAttributes [out] - Specifies the OBJECT_ATTRIBUTES structure to initialize.
- ObjectName [in] - A pointer to a Unicode string that contains name of the object for
- which a handle is to be opened. This must either be a fully qualified object name,
- or a relative path name to the object directory specified by the RootDirectory parameter.
- Attributes [in] - Specifies one or more of the flags Indicating where this detach request came from.
- RootDirectory [in] - A handle to the root object directory for the path name specified in the ObjectName parameter.
- If ObjectName is a fully qualified object name, RootDirectory is NULL. Use ZwCreateDirectoryObject
- to obtain a handle to an object directory.
- SecurityDescriptor [in, optional] - Specifies a security descriptor to apply to an object when it is created.
- This parameter is optional. Drivers can specify NULL to accept the default security for the object.
- For more information, see the following Remarks section.
- Return Value:
- Returns the status of this operation.
- --*/
- NTSTATUS FLTAPI CommPortConnect(
- IN PFLT_PORT ClientPort,
- IN PVOID ServerPortCookie,
- IN PVOID ConnectionContext,
- IN ULONG SizeOfContext,
- OUT PVOID* ConnectionCookie )
- {
- // Check basic "credentials"
- // TODO: check: we should to understand, connection is estabilished with our service, not third-party
- if(DRIVER_DATA.procinfo.CurrentProcessID != PsGetCurrentProcessId())
- {
- return STATUS_ACCESS_DENIED;
- }
- // We shoud to understand who tries to manipulate us
- DRIVER_DATA.procinfo.CurrentProcessID = PsGetCurrentProcessId();
- DRIVER_DATA.procinfo.CurrentThreadID = PsGetCurrentThreadId();
- // Remember connection details
- DRIVER_DATA.Connection.ClientPort = ClientPort;
- // All is ok, connection estabilished
- return STATUS_SUCCESS;
- }
- /*++
- Routine Description:
- This function is called when user-mode connects to the server port - to estabilish a
- connection.
- Arguments:
- InitializedAttributes [out] - Specifies the OBJECT_ATTRIBUTES structure to initialize.
- ObjectName [in] - A pointer to a Unicode string that contains name of the object for
- which a handle is to be opened. This must either be a fully qualified object name,
- or a relative path name to the object directory specified by the RootDirectory parameter.
- Attributes [in] - Specifies one or more of the flags Indicating where this detach request came from.
- RootDirectory [in] - A handle to the root object directory for the path name specified in the ObjectName parameter.
- If ObjectName is a fully qualified object name, RootDirectory is NULL. Use ZwCreateDirectoryObject
- to obtain a handle to an object directory.
- SecurityDescriptor [in, optional] - Specifies a security descriptor to apply to an object when it is created.
- This parameter is optional. Drivers can specify NULL to accept the default security for the object.
- For more information, see the following Remarks section.
- Return Value:
- Returns the status of this operation.
- --*/
- void FLTAPI CommPortDisconnect( IN PVOID ConnectionCookie )
- {
- FltCloseClientPort(DRIVER_DATA.fltHandle, &DRIVER_DATA.Connection.ClientPort);
- DRIVER_DATA.procinfo.CurrentProcessID = NULL;
- }
- /*++
- Routine Description:
- This function is called when user-mode connects to the server port - to estabilish a
- connection.
- Arguments:
- PortCookie [in] - Pointer to information that uniquely identifies this client port. This information is defined by the
- minifilter driver. When the client port was created, the minifilter driver returned this context pointer
- in the ConnectionPortCookie parameter of its ConnectNotifyCallback routine.
- InputBuffer [in,opt] - Pointer to a caller-allocated buffer containing the message to be sent to the minifilter driver.
- Note that InputBuffer is a pointer to a raw, unlocked user-mode buffer. This pointer is valid only
- in the context of the user-mode process and must only be accessed from within a try/except block.
- The filter manager calls ProbeForRead to validate this pointer, but it does not ensure that the buffer
- is properly aligned. If the buffer contains structures that have alignment requirements, the minifilter
- driver is responsible for performing any necessary alignment checks. To do this, the minifilter driver
- can use the IS_ALIGNED macro as shown in the MiniSpy sample minifilter driver.
- This parameter is optional and can be NULL.
- InputBufferLength [in] - Size, in bytes, of the buffer that InputBuffer points to. This parameter is ignored if InputBuffer is NULL.
- OutputBuffer [ouy,opt] - Pointer to a caller-allocated buffer that receives the reply (if any) from the minifilter driver.
- Note that OutputBuffer is a pointer to a raw, unlocked user-mode buffer. This pointer is valid only in the
- context of the user-mode process and must only be accessed from within a try/except block.
- The filter manager calls ProbeForWrite to validate this pointer, but it does not ensure that the buffer is
- properly aligned. If the buffer contains structures that have alignment requirements, the minifilter driver is
- responsible for performing any necessary alignment checks. To do this, the minifilter driver can use the IS_ALIGNED
- macro as shown in the MiniSpy sample minifilter driver.
- This parameter is optional and can be NULL.
- OutputBufferLength [out] - Size, in bytes, of the buffer that OutputBuffer points to. This parameter is ignored if OutputBuffer is NULL.
- ReturnOutputBufferLength [in] - Pointer to a caller-allocated variable that receives the number of bytes returned in the buffer that OutputBuffer points to.
- MaxConnections [in] - Maximum number of simultaneous client connections to be allowed for this server port. This parameter is required and must be greater than zero.
- --*/
- NTSTATUS FLTAPI CommPortMessageNotify (
- IN PVOID PortCookie,
- IN PVOID InputBuffer OPTIONAL,
- IN ULONG InputBufferLength,
- OUT PVOID OutputBuffer OPTIONAL,
- IN ULONG OutputBufferLength,
- OUT PULONG ReturnOutputBufferLength
- )
- {
- MINIFILTER_COMMAND command;
- NTSTATUS status;
- if(InputBufferLength == 0)
- {
- return STATUS_SUCCESS;
- }
- DbgPrint("Message from service recieved: %x, size: %d", InputBuffer, InputBufferLength);
- if((InputBufferLength >= (FIELD_OFFSET(COMMAND_MESSAGE, Command) +
- sizeof(MINIFILTER_COMMAND))))
- {
- try {
- //
- // Probe and capture input message: the message is raw user mode
- // buffer, so need to protect with exception handler
- //
- command = ((PCOMMAND_MESSAGE) InputBuffer)->Command;
- } except (EXCEPTION_EXECUTE_HANDLER)
- {
- return GetExceptionCode();
- }
- switch(command)
- {
- case GetVersion:
- //
- // Return version of the filter driver. Verify
- // we have a valid user buffer including valid
- // alignment
- //
- if ((OutputBufferLength < sizeof( PFILTERVERSION )) ||
- (OutputBuffer == NULL)) {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- //
- // Validate Buffer alignment. If a minfilter cares about
- // the alignment value of the buffer pointer they must do
- // this check themselves. Note that a try/except will not
- // capture alignment faults.
- //
- if (!IS_ALIGNED(OutputBuffer,sizeof(ULONG))) {
- status = STATUS_DATATYPE_MISALIGNMENT;
- break;
- }
- //
- // Protect access to raw user-mode output buffer with an
- // exception handler
- //
- try {
- ((PFILTERVERSION)OutputBuffer)->Major = MINISPY_MAJ_VERSION;
- ((PFILTERVERSION)OutputBuffer)->Minor = MINISPY_MIN_VERSION;
- } except ( EXCEPTION_EXECUTE_HANDLER ) {
- return GetExceptionCode();
- }
- *ReturnOutputBufferLength = sizeof( PFILTERVERSION );
- status = STATUS_SUCCESS;
- break;
- default:
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- return status;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement