串口过滤

Posted onetrainee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了串口过滤相关的知识,希望对你有一定的参考价值。

《Windows内核安全与驱动开发》阅读笔记 -- 索引目录

https://github.com/minglinchen/WinKernelDev/tree/master/comcap

串口过滤

 

1. 串口过滤思路

  每一个串口在 Device 文件夹下都有一个对应的设备,每个设备及对应的一个设备栈;

  我们自己的驱动来生成过滤设备,然后依次绑定这些设备的设备栈,处理各个设备栈中的IRP请求,这样就实现了设备过滤。

 

2. 如何来找到对应的设备

  其串口设备都是以Serial1,Serial2,Serial3命名的,如下图:

  技术图片

   因而内核中又提供 IoGetDeviceObjectPointer 函数,该函数可以通过一个设备名称UnicodeString来获取该设备指针,

  这样就很容易来获取相应的设备对象,进行绑定;另外还要了解RtlStringCchPrintfW这个函数,可以格式化输入。

  则下面的代码就很好理解,其就是初始化UNICODE字符串进行绑定:

  技术图片

 

3. 如何来进行绑定设备

  经过上面那步,我们已经获取绑定的目标设备,下面就是需要绑定设备了。

  内核提供了一个函数 IoAttachDeviceToDeviceStack,该函数可以附着设备,同时IoDetachDevice可以来解除设备的附加;

  下面举一个该设备的例子,很好理解:

   技术图片

  因此我们可以看到下面代码,很明显就是来绑定设备:

  技术图片

 

4. 如何来创建过滤设备

  上面我们已经讲了如何将过滤设备绑定到目标的设备栈中,现在有一个问题,我们应该如何创建过滤设备。

  其实创建设备,我们在之前的通讯都已经反复使用了,这并不复杂,但是设备的各种属性应该如何处理呢?

  其实对应的操作很简单,我们设置与过滤目标的属性值相同即可。

  1)DeviceType 

    我们在用IoCreateDevice时要标记设备属性,我们之前在创建设备时一般会设置为UNKNOWN类型,但是现在我们可以使用目标设置的DeviceType,

    因此我们可以看到如下代码,这种写法是非常好理解的。

     技术图片

  2)Flags

    设备中的Flags是一些DO_XXX的参数,我们需要设置的是内存方式(缓冲、直接、MDL)、初始化完成与 DO_POWER_PAGABLE。

  3)Characteristics

    我们判断其是否设置 FILE_DEVICE_SECURE_OPEN 属性,这些都是默认的。

    因此我们可以看到下面初始化代码:

    技术图片

 

 

5. IRP处理

  我们现在已经绑定了过滤设备,之后所有会发送到DeviceSerial0,1,...的消息都会被我们驱动的过滤设备接收到;

  其设备接收之后会根据IRP的MajorFunction发送到对应的派发函数,我们现在直接全部绑定一个派发函数,集中处理IRP。

  对于IRP的处理,我们有博客:

  现在,我们只是简单的处理 IRP_MJ_WRITE , 直接打印过来即可,至于其他的,直接跳过,不修改参数,调用IoCallDriver,

  下一个设备会原封不动地处理该参数,这很容易理解。

  技术图片

 

6. 程序整体代码逻辑的处理

  上面我们已经讨论过其单个的实现细节,但是其程序总体是如何设计的呢?

  首先,我们默认是绑定DeviceSerial0 ~ 31 的,因此需要创建数组,需要创建哪几个数组呢?

  依次是 原顶层设备指针、过滤设备指针  , 这里不需要目标的过滤设备指针,因为原来顶层设备指针就可以来代替。

  因此我们可以看到两个数组:

  技术图片

 

以上是关于串口过滤的主要内容,如果未能解决你的问题,请参考以下文章

CommMonitor8.0串口过滤工具(serial port monitor)

CommMonitor8.0 串口过滤驱动 SDK DLL版本 C#/Delphi调用DEMO

串口状态机,这东西很好用啊

串口状态机,这东西很好用啊

如何使用commmonitor串口监控工具 6.1

CommMonitor监听串口数据的时候出现下面这个问题是怎么回事?有啥解决的办法?