[原创] 驱动通信:通过PIPE管道与内核层通信
2022-10-1 08:40 3455
在本人前一篇博文《驱动开发:通过ReadFile与内核层通信》
详细介绍了如何使用应用层ReadFile
系列函数实现内核通信,本篇将继续延申这个知识点,介绍利用PIPE
命名管道实现应用层与内核层之间的多次通信方法。
在Windows编程中,数据重定向需要用到管道PIPE,管道是一种用于在进程间共享数据的机制,通常由两端组成,数据从一端流入则必须从令一端流出,也就是一读一写,利用这种机制即可实现进程间直接通信。管道的本质其实是一段共享内存区域,多数情况下管道是用于应用层之间的数据交换的,其实驱动中依然可以使用命名管道实现应用层与内核层的直接通信。
那么如何在内核中创建一个管道?请看以下代码片段,以及MSDN针对函数的解析。
InitializeObjectAttributes
OBJECT_ATTRIBUTES
结构,它设置将被打开的对象句柄的属性。然后调用方可以将一个指向该结构的指针传递给实际打开句柄的例程。ZwCreateFile
objAttr
这个文件。KeInitializeEvent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
原理就是打开\\DosDevices\\Pipe\\LySharkPipeConn
文件,然后将事件对象初始化为同步状态。
接下来就是如何将数据发送给应用层的问题,发送问题可以调用ZwWriteFile
这个内核函数,如下我们实现的效果是将一个char
类型的字符串传输给应用层。
1 2 3 4 5 6 7 8 9 |
|
内核层的核心代码就是如上这些,将这些整合在一起完整代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
|
内核中创建了命名管道,客户端就需要创建一个相同名称的管道,并通过ReadFile
函数读取管道中的数据,应用层核心代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
至此将驱动签名后运行,并迅速打开应用层程序等待同步发送事件,即可得到如下返回结果。
此处有必要解释一下为什么会写出错误,很简单这段代码并没有控制何时触发事件,导致两边不同步,因为只是一个案例用于演示管道的应用方法,所以大家不要太较真,如果不想出错误这段代码还有很多需要改进的地方。
管道不仅可以传输字符串完全可以传输结构体数据,如下我们定义一个Networkreport
结构体,并通过管道的方式多次传输给应用层,这部分传输模式适合用于驱动中一次性突出多个结构体,例如进程列表的输出,ARK工具中的驱动列表输出等功能的实现。
驱动层完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
|
应用层完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
|
结构体一次性输出多个,效果如下所示: