minifilter -- User Mode Communication


Filter Communication Port Object

To implement security and enable multiplecommunication channels, a new object has been introduced called a minifiltercommunication port.  It is intended to beused for kernel-user communication and vice versa.  Kernel-kernel communication is not presentlysupported.  A port is a named NT object,with a security descriptor.

为了实现安全并且多条通信信道,minifilter通信端口被引入了系统,它被用来实现内核与用户层的通信,而内核到内核的通信现在还不支持。一个端口是具有安全描述符的具名NT对象。

Filter Manager creates a new object type,FilterConnectionPort, to facilitate this. Filter Manager creates this new object type during its driver entryinitialization before any minifilters are loaded.

为了方便使用通信端口,过滤管理器创建了一种新的对象类型FilterConnectionPort。过滤管理器在任何minifilter驱动加载之前创建了这个新的对象类型。

Only kernel-mode drivers can create a minifiltercommunication port, with the following API:

只有内核驱动可以创建minifilter通信端口,创建端口的API如下:

NTSTATUS

FltCreateCommunicationPort(

    IN PFLT_FILTER Filter,

    OUT PHANDLE PortHandle,

    IN POBJECT_ATTRIBUTES ObjectAttributes,

    IN PVOID ServerPortCookie OPTIONAL,

    IN PFLT_CONNECT_NOTIFYConnectNotifyCallback,

    IN PFLT_DISCONNECT_NOTIFYDisconnectNotifyCallback,

    IN PFLT_MESSAGE_NOTIFYMessageNotifyCallback,

    IN ULONG MaxConnections

    );

The Filter is the handle to thefilter object of the minifilter that is creating this communication portobject.  The handle created by asuccessful call to FltCreateCommunicationPort() is returned in the PortHandle parameter.

Filter参数为要创建端口端口的minifilter驱动的过滤对象。FltCreateCommunicationPort()返回的端口句柄保存在参数PortHandle中。

As with other NT objects, the ObjectAttributes parameter defines the OBJECT_ATTRIBUTES structureto initialize the name, object attribute flags and security descriptor for thenew communication port object being created. Note that for the communication port objects, the object attribute OBJ_KERNEL_HANDLE must be specified since this object can only be created as kernelobjects.

和其它NT对象一样,ObjectAttributes为创建的端口对象定义了结构体初始化名字、对象属性及安全描述符,对于通信端口对象,对象属性OBJ_KERNEL_HANDLE必须被指定,因为对象只能被创建为内核对象。

The ServerPortCookie is a contextthat minifilters can associate with the port and this context is opaque to theFilter Manager. All connect/disconnect notifications to the minifilter for thisport will be passed this cookie.  This isuseful for minifilters which create an array of ports since the cookie can beused to identify which port in the array is being accessed without definingunique port notification routines for each port in the array.

ServerPortCookie是minifilter驱动用来关联端口的上下文,并且它对过滤管理器是透明的,所有的连接、断开通知函数都将被传递这个cookie。如果一个驱动创建了多个通信端口,可以使用它来区分端口而不用为每个端口定义不同的通知函数。

The caller also registers three callbacks when acommunication port is created:

在通信端口被创建的时候,调用者也定义了3个回调函数。

·         ConnectNotifyCallback():  This will be calledwhenever a user mode process tries to open the port. The minifilter will havethe option to fail the connection request. The notify routine will receive a handle that the minifilter must usefor communicating on this connection. Each connection has a unique handle. The ServerPortCookie associated with the server port will also be passed in. Theminifilter may fill in the ConnectionCookie argument with a context that will be passed in to all furtheruser-kernel messages and the disconnect routine for this connection.

·         DisconnectNotifyCallback():  This will be called whenthe port is closed by user mode (i.e. the handle count goes to zero).

·         MessageNotifyCallback():  This is called whenever amessage is received.

·        ConnectNotifyCallback():当用户模式进程尝试打开这个端口时,这个回调函数将被调用。Minifilter可以选择使这个连接请求失败。这个通知函数将接收一个句柄。每个连接都有一个不同的句柄,而minifilter驱动使用这个句柄进行通信。与服务端口关联的ServerPortCookie也会作为参数传递过来。Minifilter驱动可能设置ConnectionCookie参数与一个上下文关联,而其作为参数将被传递给消息传送及连接断开函数。

·         DisconnectNotifyCallback():  端口被用户进程关闭时此回调函数将被调用。

·         MessageNotifyCallback(): 接收消息时此回调函数将被调用。

The MaxConnections specifies the maximum number ofoutstanding connections that will be allowed on this communication port.  There is no defaultvalue, but this value must be greater than 0.

//WDK Doc: Maximum number of simultaneous clientconnections to be allowed for this server port. This parameter is required andmust be greater than zero

MaxConnections指定同时允许的最大客户端连接数,这个参数必须指定并且必须大于0.

There is no guarantee that the object name willbe created in the root of the name space – it’s possible that the FilterManager may map it under the \FileSystem\Filters object directory internally. If such a mapping occurs, it will be transparent to the minifilter andthe user-mode application.  Whenreferencing the communication port by name, both components should use the samename.  The Scanner minifilter exampleshow how this is done.

不保证创建的端口对象名称存在于命名空间的根上,过滤管理器可能将其放在\FileSystem\Filters目录中。如果是这种映射,它对minifilter驱动及用户程序都是透明的。通过名字引用端口对象时,双方(Kernel/UserMode)应该使用相同的名字。

In association with the new object type, newaccess types will be introduced for objects of this type. The minimal new accesstypes are:

与通信端口关联的访问类型如下:

·        FLT_PORT_CONNECT

·        FLT_PORT_ALL_ACCESS

These are the access types that callers of thisAPI can grant to users when constructing the security descriptor for the objectvia InitializeObjectAttributes().

构造安全描述符并使用InitializeObjectAttributes()初始化对象时这些访问权限将赋给用户。

PS:翻译的不好,其实是调用FltBuildDefaultSecurityDescriptor可以创建指定访问权限的安全描述符。

At the moment FLT_PORT_CONNECT will besufficient to let user mode connect to the port and both send and receivemessages.

当前来说,FLT_PORT_CONNECT对用户来说已经足够,可以用户发送及接收消息。

When a minifilter creates the port, itimplicitly starts listening on the port for incoming connections. It continuesto listen until it closes the handle to the port by calling ZwClose().

Minifilter驱动创建完端口后,它开始为连接监听端口直到调用ZwClose关闭端口。

1.2. Connecting to Communication Port from User Mode

The minifilter communication port model – likethe legacy model – is asymmetric.  Thekernel-mode end creates the communication port. The user-mode end connects toit.  There is an API to open the port forthe user-mode application.  When aconnection is established, theConnectNotify() routine is called notifying the minifilter of the connectioncreation request as well the minifilter end of the port handle that should beused to send messages across this connection.

Minifilter通信端口模型是不对称的。内核创建端口,用户进程调用API连接端口。连接建立后,ConnectNotify回调被调用通知minifilter驱动创建连接并且minifilter获得一个端口句柄用来在此连接上发送消息。

The prototype of the user-mode API to connect tothe port is:

HRESULT

FilterConnectCommunicationPort(

    IN LPWSTR lpPortName,

    IN DWORD dwOptions,

    IN LPVOID lpContext,

    IN WORD wSizeOfContext,

    IN LPSECURITY_ATTRIBUTESlpSecurityAttributes,

    OUT HANDLE *hPort

);

The lpPortName is a pointer to awide-character string that specifies the name of the port to which toconnect.  This name should be the samename used by the minifilter which created the port.  The port name may start with a ‘\’ –indicating it is in the root directory. Filter Manager may however open it relatively in the actual appropriatedirectory that hosts minifilter communication ports.

lpPortName是指定连接端口名称的Unicode字符串,这个名字应该和minifilter创建的端口名称一致,若端口名称以’\’开始,说明它在根目录,而过滤管理器可能在存储通信端口的相对目录打开它。

The dwOptions parameter iscurrently unused.

dwOptions参数未被使用。

The lpContext is a pointer to anopaque parameter that will be passed to the minifilter’s ConnectNotify() routine.  This can be used toauthenticate that the application requesting to create the communicationchannel is the expected application of the appropriate version.  The wSizeOfContext specifies thesize of lpContext in bytes.

lpContext是一个不透明的参数,它将被传递到minifilter的ConnectNotify()回调函数。它可以用来验证要求要求连接通信的程序是期望的版本合适的应用程序,wSizeOfContext指定lpContext缓冲区的大小。

ConnectNotify函数原型如下:

typedef NTSTATUS
(*PFLT_CONNECT_NOTIFY) (
      IN PFLT_PORT ClientPort,
      IN PVOID ServerPortCookie,
      IN PVOID ConnectionContext,
      IN ULONG SizeOfContext,
      OUT PVOID *ConnectionPortCookie
      );

The lpSecurityAttributesspecifies the security attributes for the user end of the connection, and ifthe handle will be inherited.

lpSecurityAttributes指定用户程序的安全描述符,并且指定句柄是否被继承。

If the call is not successful, the appropriateHRESULT will be returned.

如果调用失败,合适的错误码HRESULT被返回。

The returned handle may be closed/duplicated etcvia the usual APIs. It can also be associated with an I/O completion port.

返回的句柄可以关闭、被复制,也可以与IO完成端口关联。

When this API is called, a new kernel-mode onlyunnamed port object is created (of type FilterCommunicationPort)thatis used to represent the connection. The minifilter will be notified by callingthe ConnectNotify() routine it supplied in the create operation for the server port, andgiven the handle to the connection port which should be used for sendingmessages from the kernel-side.

这个API被调用后,一个新的内核未具名端口对象(类型为FilterCommunicationPort)被创建,函数ConnectNotify()被调用通知minifilter驱动连接创建,并且提供了一个指向连接端口的句柄,通过这个句柄内核可以用来发送消息。

Of course if the caller does not have sufficientaccess to the server port, or the maximum number of connections are exceededthis will fail appropriately.

如果调用者没有足够的权限或者超过了最大连接数,连接将失败。

1.3. Disconnecting from the Communication Port

When the user-mode calls CloseHandle() on the handle obtained for the connection or the kernel-mode sidecalls ZwClose() on the connection port handle, the connection is broken.

如果用户进程调用CloseHandle或者内核调用ZwClose,连接将被中断。

The minifilter’s DisconnectNotify() routine will be called only when the user mode closes its handle.

只有当用户进程关闭句柄时,minifilter的DisconnectNotify函数才会被调用。

Ideally the minifilter should always close itsend of the connection in the DisconnectNotify() routine.  If a minifiltercloses the handle at other times, it should make sure the handle will not bedouble-closed in its DisconnectNotify() by using some sort of synchronization.

理想情况下minifilter驱动应该在回调DisconnectNotify函数中关闭连接(ZwClose)。如果minifilter在其它时机关闭了句柄,它应该在DisconnectNotify加入同步机制确保句柄应该没有被双重关闭。

When a communication port is disconnected oneither the kernel or user-mode end:

1.    Any user-mode waiters (via FilterGetMessage()) are flushed out and completed with STATUS_FLT_PORT_DISCONNECTED (which translates to win32 error ERROR_DISCONNECTED )

2.    Any kernel mode senders thatare blocked on waiters are woken up and completed with STATUS_FLT_PORT_DISCONNECTED

3.    The port is ‘invalidated’ so nomore futures waiters/senders will be allowed.

通信端口被关闭后:

1.     所有的用户进程等待(通过FilterGetMessage())返回STATUS_FLT_PORT_DISCONNECTED

2.     所有的内核发送者返回STATUS_FLT_PORT_DISCONNECTED

3.     端口不再有效,任何在此端口上的等待、发送都不再允许。

The minifilter can always close the server portby calling ZwClose() on the server port handle. This does not force existing connections to break, but simply stops theminifilter from accepting any more connections.

Minifilter驱动可以调用ZwClose关闭服务端口,但这不会关闭已有的连接,只是不再接受新的连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值