驱动开发:内核封装WSK网络通信接口
本章LyShark
将带大家学习如何在内核中使用标准的Socket
套接字通信接口,我们都知道Windows
应用层下可直接调用WinSocket
来实现网络通信,但在内核模式下应用层API接口无法使用,内核模式下有一套专有的WSK
通信接口,我们对WSK进行封装,让其与应用层调用规范保持一致,并实现内核与内核直接通过Socket
通信的案例。
当然在早期如果需要实现网络通信一般都会采用TDI
框架,但在新版本Windows10
系统上虽然依然可以使用TDI接口,但是LyShark
并不推荐使用,因为微软已经对接口搁置了,为了使WSK通信更加易用,我们需要封装内核层中的通信API,新建LySocket.hpp
头文件,该文件中封装了WSK通信API接口,其封装格式与应用层接口保持了高度一致,当需要在内核中使用Socket通信时可直接引入本文件。
我们需要使用WDM
驱动程序,并配置以下参数。
- 配置属性 -> 连接器 -> 输入-> 附加依赖 -> $(DDK_LIB_PATH)\Netio.lib
- 配置属性 -> C/C++ -> 常规 -> 设置 警告等级2级 (警告视为错误关闭)
配置好以后,我们就开始吧,先来看看服务端如何实现!
对于服务端
来说,驱动通信必须保证服务端开启多线程来处理异步请求,不然驱动加载后系统会处于等待状态,而一旦等待则系统将会卡死,那么对于服务端DriverEntry
入口说我们不能让其等待,必须使用PsCreateSystemThread
来启用系统线程,该函数属于WDM的一部分,官方定义如下;
NTSTATUS PsCreateSystemThread( |
我们使用PsCreateSystemThread
函数开辟线程TcpListenWorker
在线程内部执行如下流程启动驱动服务端,由于我们自己封装实现了标准接口组,所以使用起来几乎与应用层无任何差异了。
- CreateSocket 创建套接字
- Bind 绑定套接字
- Accept 等待接收请求
- Receive 用于接收返回值
- Send 用于发送返回值
// 署名权 |
对于客户端来说,只需要创建套接字并连接到指定地址即可,这个过程大体上可以总结为如下;
- CreateSocket 创建套接字
- Bind 绑定套接字
- Connect 链接服务端驱动
- Send 发送数据到服务端
- Receive 接收数据到服务端
// 署名权 |
编译两个驱动程序,首先运行server.sys
驱动,运行后该驱动会在后台等待客户端连接,接着运行client.sys
屏幕上可输出如下提示,说明通信已经建立了。