📄 minispy.c
字号:
/*++
Copyright (c) 1989-2002 Microsoft Corporation
Module Name:
MiniSpy.c
Abstract:
This is the main module for the MiniSpy mini-filter.
Environment:
Kernel mode
--*/
#include "mspyKern.h"
//
// Global variables
//
MINISPY_DATA MiniSpyData;
//---------------------------------------------------------------------------
// Function prototypes
//---------------------------------------------------------------------------
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
SpyMessage (
IN PVOID ConnectionCookie,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferSize,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferSize,
OUT PULONG ReturnOutputBufferLength
);
NTSTATUS
SpyConnect(
IN PFLT_PORT ClientPort,
IN PVOID ServerPortCookie,
IN PVOID ConnectionContext,
IN ULONG SizeOfContext,
OUT PVOID *ConnectionCookie
);
VOID
SpyDisconnect(
IN PVOID ConnectionCookie
);
//---------------------------------------------------------------------------
// Assign text sections for each routine.
//---------------------------------------------------------------------------
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, SpyFilterUnload)
#pragma alloc_text(PAGE, SpyQueryTeardown)
#pragma alloc_text(PAGE, SpyConnect)
#pragma alloc_text(PAGE, SpyDisconnect)
#pragma alloc_text(PAGE, SpyMessage)
#endif
//---------------------------------------------------------------------------
// ROUTINES
//---------------------------------------------------------------------------
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
This routine is called when a driver first loads. Its purpose is to
initialize global state and then register with FltMgr to start filtering.
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:
Status of the operation.
--*/
{
PSECURITY_DESCRIPTOR sd;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uniString;
NTSTATUS status;
try {
//
// Initialize global data structures.
//
MiniSpyData.LogSequenceNumber = 0;
MiniSpyData.MaxRecordsToAllocate = DEFAULT_MAX_RECORDS_TO_ALLOCATE;
MiniSpyData.RecordsAllocated = 0;
MiniSpyData.NameQueryMethod = DEFAULT_NAME_QUERY_METHOD;
MiniSpyData.DriverObject = DriverObject;
InitializeListHead( &MiniSpyData.OutputBufferList );
KeInitializeSpinLock( &MiniSpyData.OutputBufferLock );
ExInitializeNPagedLookasideList( &MiniSpyData.FreeBufferList,
NULL,
NULL,
0,
RECORD_SIZE,
SPY_TAG,
0 );
//
// Read the custom parameters for MiniSpy from the registry
//
SpyReadDriverParameters(RegistryPath);
//
// Now that our global configuration is complete, register with FltMgr.
//
status = FltRegisterFilter( DriverObject,
&FilterRegistration,
&MiniSpyData.Filter );
if (!NT_SUCCESS( status )) {
leave;
}
status = FltBuildDefaultSecurityDescriptor( &sd,
FLT_PORT_ALL_ACCESS );
if (!NT_SUCCESS( status )) {
leave;
}
RtlInitUnicodeString( &uniString, MINISPY_PORT_NAME );
InitializeObjectAttributes( &oa,
&uniString,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
sd );
status = FltCreateCommunicationPort( MiniSpyData.Filter,
&MiniSpyData.ServerPort,
&oa,
NULL,
SpyConnect,
SpyDisconnect,
SpyMessage,
1 );
FltFreeSecurityDescriptor( sd );
if (!NT_SUCCESS( status )) {
leave;
}
//
// We are now ready to start filtering
//
status = FltStartFiltering( MiniSpyData.Filter );
} finally {
if (!NT_SUCCESS( status ) ) {
if (NULL != MiniSpyData.ServerPort) {
FltCloseCommunicationPort( MiniSpyData.ServerPort );
}
if (NULL != MiniSpyData.Filter) {
FltUnregisterFilter( MiniSpyData.Filter );
}
ExDeleteNPagedLookasideList( &MiniSpyData.FreeBufferList );
}
}
return status;
}
NTSTATUS
SpyConnect(
IN PFLT_PORT ClientPort,
IN PVOID ServerPortCookie,
IN PVOID ConnectionContext,
IN ULONG SizeOfContext,
OUT PVOID *ConnectionCookie
)
/*++
Routine Description
This is called when user-mode connects to the server
port - to establish a connection
Arguments
ClientPort - This is the pointer to the client port that
will be used to send messages from the filter.
ServerPortCookie - unused
ConnectionContext - unused
SizeofContext - unused
ConnectionCookie - unused
Return Value
STATUS_SUCCESS - to accept the connection
--*/
{
PAGED_CODE();
UNREFERENCED_PARAMETER( ServerPortCookie );
UNREFERENCED_PARAMETER( ConnectionContext );
UNREFERENCED_PARAMETER( SizeOfContext);
UNREFERENCED_PARAMETER( ConnectionCookie );
ASSERT( MiniSpyData.ClientPort == NULL );
MiniSpyData.ClientPort = ClientPort;
return STATUS_SUCCESS;
}
VOID
SpyDisconnect(
IN PVOID ConnectionCookie
)
/*++
Routine Description
This is called when the connection is torn-down. We use it to close our handle to the connection
Arguments
ConnectionCookie - unused
Return value
None
--*/
{
PAGED_CODE();
UNREFERENCED_PARAMETER( ConnectionCookie );
//
// Close our handle
//
FltCloseClientPort( MiniSpyData.Filter, &MiniSpyData.ClientPort );
}
NTSTATUS
SpyFilterUnload (
IN FLT_FILTER_UNLOAD_FLAGS Flags
)
/*++
Routine Description:
This is called when a request has been made to unload the filter. Unload
requests from the Operation System (ex: "sc stop minispy" can not be
failed. Other unload requests may be failed.
You can disallow OS unload request by setting the
FLTREGFL_DO_NOT_SUPPORT_SERVICE_STOP flag in the FLT_REGISTARTION
structure.
Arguments:
Flags - Flags pertinent to this operation
Return Value:
Always success
--*/
{
UNREFERENCED_PARAMETER( Flags );
PAGED_CODE();
//
// Close the server port. This will stop new connections.
//
FltCloseCommunicationPort( MiniSpyData.ServerPort );
FltUnregisterFilter( MiniSpyData.Filter );
SpyEmptyOutputBufferList();
ExDeleteNPagedLookasideList( &MiniSpyData.FreeBufferList );
return STATUS_SUCCESS;
}
NTSTATUS
SpyQueryTeardown (
IN PCFLT_RELATED_OBJECTS FltObjects,
IN FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
)
/*++
Routine Description:
This allows our filter to be manually detached from a volume.
Arguments:
FltObjects - Contains pointer to relevant objects for this operation.
Note that the FileObject field will always be NULL.
Flags - Flags pertinent to this operation
Return Value:
--*/
{
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( Flags );
PAGED_CODE();
return STATUS_SUCCESS;
}
NTSTATUS
SpyMessage (
IN PVOID ConnectionCookie,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferSize,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferSize,
OUT PULONG ReturnOutputBufferLength
)
/*++
Routine Description:
This is called whenever a user mode application wishes to communicate
with this minifilter.
Arguments:
ConnectionCookie - unused
OperationCode - An identifier describing what type of message this
is. These codes are defined by the MiniFilter.
InputBuffer - A buffer containing input data, can be NULL if there
is no input data.
InputBufferSize - The size in bytes of the InputBuffer.
OutputBuffer - A buffer provided by the application that originated
the communication in which to store data to be returned to this
application.
OutputBufferSize - The size in bytes of the OutputBuffer.
ReturnOutputBufferSize - The size in bytes of meaningful data
returned in the OutputBuffer.
Return Value:
Returns the status of processing the message.
--*/
{
MINISPY_COMMAND command;
NTSTATUS status;
PAGED_CODE();
UNREFERENCED_PARAMETER( ConnectionCookie );
//
// **** PLEASE READ ****
//
// The INPUT and OUTPUT buffers are raw user mode addresses. The filter
// manager has already done a ProbedForRead (on InputBuffer) and
// ProbedForWrite (on OutputBuffer) which guarentees they are valid
// addresses based on the access (user mode vs. kernel mode). The
// minifilter does not need to do their own probe.
//
// The filter manager is NOT doing any alignment checking on the pointers.
// The minifilter must do this themselves if they care (see below).
//
// The minifilter MUST continue to use a try/except around any access to
// these buffers.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -