驱动开发:内核封装TDI网络通信接口

2024-02-16 09:20

本文主要是介绍驱动开发:内核封装TDI网络通信接口,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在上一篇文章《驱动开发:内核封装WSK网络通信接口》中,LyShark已经带大家看过了如何通过WSK接口实现套接字通信,但WSK实现的通信是内核与内核模块之间的,而如果需要内核与应用层之间通信则使用TDK会更好一些因为它更接近应用层,本章将使用TDK实现,TDI全称传输驱动接口,其主要负责连接Socket和协议驱动,用于实现访问传输层的功能,该接口比NDIS更接近于应用层,在早期Win系统中常用于实现过滤防火墙,同样经过封装后也可实现通信功能,本章将运用TDI接口实现驱动与应用层之间传输字符串,结构体,多线程收发等技术。

  • TDI传输字符串
  • TDI多线程收发
  • TDI传数结构实现认证

TDI 传输字符串: 服务端在应用层侦听,客户端是驱动程序,驱动程序加载后自动连接应用层并发送消息。

首先来看应用层(服务端)代码,具体我就不说了,来看教程的都是有基础的。

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com#define _CRT_SECURE_NO_WARNINGS
#include <iostream>  
#include <winsock2.h>  #pragma comment(lib,"ws2_32.lib")
#define PORT 8888 int main(int argc, char *argv[])
{printf("hello lyshark.com \n");WSADATA WSAData;SOCKET sock, msgsock;struct sockaddr_in ServerAddr;if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR){ServerAddr.sin_family = AF_INET;ServerAddr.sin_port = htons(PORT);ServerAddr.sin_addr.s_addr = INADDR_ANY;sock = socket(AF_INET, SOCK_STREAM, 0);int BindRet = bind(sock, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr));int LinsRet = listen(sock, 10);}while (1){char buf[1024] = { 0 };msgsock = accept(sock, (LPSOCKADDR)0, (int *)0);memset(buf, 0, sizeof(buf));recv(msgsock, buf, 1024, 0);printf("内核返回: %s \n", buf);char send_buffer[1024] = { 0 };memset(send_buffer, 0, 1024);strcpy(send_buffer, "Hi,R0 !");send(msgsock, send_buffer, strlen(send_buffer), 0);closesocket(msgsock);}closesocket(sock);WSACleanup();return 0;
}

再来是驱动层代码,如下所示;

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com#include "MyTDI.hpp"// 发送接收数据
NTSTATUS SendOnRecv()
{NTSTATUS status = STATUS_SUCCESS;HANDLE hTdiAddress = NULL;HANDLE hTdiEndPoint = NULL;PDEVICE_OBJECT pTdiAddressDevObj = NULL;PFILE_OBJECT pTdiEndPointFileObject = NULL;LONG pServerIp[4] = { 127, 0, 0, 1 };LONG lServerPort = 8888;UCHAR szSendData[] = "hello lyshark";ULONG ulSendDataLength = 1 + strlen(szSendData);HANDLE hThread = NULL;// TDI初始化status = TdiOpen(&pTdiAddressDevObj, &pTdiEndPointFileObject, &hTdiAddress, &hTdiEndPoint);if (!NT_SUCCESS(status)){return STATUS_SUCCESS;}// TDI TCP连接服务器status = TdiConnection(pTdiAddressDevObj, pTdiEndPointFileObject, pServerIp, lServerPort);if (!NT_SUCCESS(status)){return STATUS_SUCCESS;}// TDI TCP发送信息status = TdiSend(pTdiAddressDevObj, pTdiEndPointFileObject, szSendData, ulSendDataLength);if (!NT_SUCCESS(status)){return STATUS_SUCCESS;}DbgPrint("发送: %s\n", szSendData);// 创建接收信息多线程, 循环接收信息char szRecvData[1024] = { 0 };ULONG ulRecvDataLenngth = 1024;RtlZeroMemory(szRecvData, ulRecvDataLenngth);// TDI TCP接收信息do{ulRecvDataLenngth = TdiRecv(pTdiAddressDevObj, pTdiEndPointFileObject, szRecvData, ulRecvDataLenngth);if (0 < ulRecvDataLenngth){DbgPrint("接收数据: %s\n", szRecvData);break;;}} while (TRUE);// 释放TdiClose(pTdiEndPointFileObject, hTdiAddress, hTdiEndPoint);return STATUS_SUCCESS;
}VOID UnDriver(PDRIVER_OBJECT driver)
{DbgPrint("驱动卸载成功 \n");
}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{for (int x = 0; x < 10; x++){SendOnRecv();}DbgPrint("驱动加载成功 \n");Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;
}

首先运行应用层开启服务端侦听,然后运行驱动程序,会输出如下信息;

TDI 多线程收发包: 实现驱动内部发送数据包后开启一个线程用于等待应用层返回并输出结果,多线程收发在发送数据包后需要创建新的线程等待接收。

首先是服务端代码。

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com#define _CRT_SECURE_NO_WARNINGS
#include <iostream>  
#include <winsock2.h>  #pragma comment(lib,"ws2_32.lib")
#define PORT 8888 int main(int argc, char *argv[])
{printf("hello lyshark.com \n");WSADATA WSAData;SOCKET sock, msgsock;struct sockaddr_in ServerAddr;if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR){ServerAddr.sin_family = AF_INET;ServerAddr.sin_port = htons(PORT);ServerAddr.sin_addr.s_addr = INADDR_ANY;sock = socket(AF_INET, SOCK_STREAM, 0);int BindRet = bind(sock, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr));int LinsRet = listen(sock, 10);}while (1){char buf[1024] = { 0 };msgsock = accept(sock, (LPSOCKADDR)0, (int *)0);memset(buf, 0, sizeof(buf));recv(msgsock, buf, 1024, 0);printf("内核返回: %s \n", buf);char send_buffer[1024] = { 0 };memset(send_buffer, 0, 1024);strcpy(send_buffer, "Hi,R0 !");send(msgsock, send_buffer, strlen(send_buffer), 0);closesocket(msgsock);}closesocket(sock);WSACleanup();return 0;
}

驱动程序代码如下,RecvThreadProc主要负责数据接收,SendThreadData负责数据发送。

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com#include "LySocket.hpp"typedef struct _MY_DATA
{PDEVICE_OBJECT pTdiAddressDevObj;PFILE_OBJECT pTdiEndPointFileObject;HANDLE hTdiAddress;HANDLE hTdiEndPoint;
}MY_DATA, *PMY_DATA;// 接收信息多线程
VOID RecvThreadProc(_In_ PVOID StartContext)
{PMY_DATA pMyData = (PMY_DATA)StartContext;NTSTATUS status = STATUS_SUCCESS;char szRecvData[1024] = { 0 };ULONG ulRecvDataLenngth = 1024;RtlZeroMemory(szRecvData, ulRecvDataLenngth);// TDI TCP接收信息do{ulRecvDataLenngth = TdiRecv(pMyData->pTdiAddressDevObj, pMyData->pTdiEndPointFileObject, szRecvData, ulRecvDataLenngth);if (0 < ulRecvDataLenngth){DbgPrint("线程句柄:%x --> 接收数据包: %s\n", pMyData->hTdiEndPoint, szRecvData);break;;}} while (TRUE);// 释放TdiClose(pMyData->pTdiEndPointFileObject, pMyData->hTdiAddress, pMyData->hTdiEndPoint);ExFreePool(pMyData);
}// 多线程发送
NTSTATUS SendThreadData()
{NTSTATUS status = STATUS_SUCCESS;HANDLE hTdiAddress = NULL;HANDLE hTdiEndPoint = NULL;PDEVICE_OBJECT pTdiAddressDevObj = NULL;PFILE_OBJECT pTdiEndPointFileObject = NULL;LONG pServerIp[4] = { 127, 0, 0, 1 };LONG lServerPort = 8888;UCHAR szSendData[] = "hello lyshark";ULONG ulSendDataLength = 1 + strlen(szSendData);HANDLE hThread = NULL;// TDI初始化status = TdiOpen(&pTdiAddressDevObj, &pTdiEndPointFileObject, &hTdiAddress, &hTdiEndPoint);if (!NT_SUCCESS(status)){return STATUS_SUCCESS;}// TDI TCP连接服务器status = TdiConnection(pTdiAddressDevObj, pTdiEndPointFileObject, pServerIp, lServerPort);if (!NT_SUCCESS(status)){return STATUS_SUCCESS;}// TDI TCP发送信息status = TdiSend(pTdiAddressDevObj, pTdiEndPointFileObject, szSendData, ulSendDataLength);if (!NT_SUCCESS(status)){return STATUS_SUCCESS;}DbgPrint("发送 %s\n", szSendData);// 创建接收信息多线程, 循环接收信息PMY_DATA pMyData = ExAllocatePool(NonPagedPool, sizeof(MY_DATA));pMyData->pTdiAddressDevObj = pTdiAddressDevObj;pMyData->pTdiEndPointFileObject = pTdiEndPointFileObject;pMyData->hTdiAddress = hTdiAddress;pMyData->hTdiEndPoint = hTdiEndPoint;PsCreateSystemThread(&hThread, 0, NULL, NtCurrentProcess(), NULL, RecvThreadProc, pMyData);
}VOID UnDriver(PDRIVER_OBJECT driver)
{DbgPrint("驱动卸载成功 \n");
}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{DbgPrint("hello lyshark.com \n");for (int x = 0; x < 10; x++){SendThreadData();}Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;
}

运行应用层服务端等待侦听,运行驱动程序输出如下效果;

TDI 传数结构实现认证: 驱动内部发送结构体给应用层,应用层验证结构体成员,此功能可实现对驱动程序的控制机制,例如是否允许驱动加载卸载等,通常用于驱动辅助认证。

应用层代码

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com#define _CRT_SECURE_NO_WARNINGS
#include <iostream>  
#include <winsock2.h>  #pragma comment(lib,"ws2_32.lib")
#define PORT 8888// 传输结构体
typedef struct
{int uuid;char username[256];char password[256];
}SocketData;int main(int argc, char *argv[])
{printf("hello lyshark.com \n");WSADATA WSAData;SOCKET sock, msgsock;struct sockaddr_in ServerAddr;if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR){ServerAddr.sin_family = AF_INET;ServerAddr.sin_port = htons(PORT);ServerAddr.sin_addr.s_addr = INADDR_ANY;sock = socket(AF_INET, SOCK_STREAM, 0);int BindRet = bind(sock, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr));int LinsRet = listen(sock, 10);}while (1){char buf[8192] = { 0 };msgsock = accept(sock, (LPSOCKADDR)0, (int *)0);memset(buf, 0, sizeof(buf));// 接收返回数据recv(msgsock, buf, sizeof(SocketData), 0);// 强转结构体SocketData* msg = (SocketData*)buf;printf("UUID = %d \n", msg->uuid);printf("名字 = %s \n", msg->username);printf("密码 = %s \n", msg->password);// 验证通过则继续使用if ((strcmp(msg->username, "lyshark") == 0) && (strcmp(msg->password, "123") == 0)){char send_buffer[8192] = { 0 };memset(send_buffer, 0, 8192);strcpy(send_buffer, "success");send(msgsock, send_buffer, strlen(send_buffer), 0);closesocket(msgsock);}// 不通过则禁止驱动加载else{char send_buffer[8192] = { 0 };memset(send_buffer, 0, 8192);strcpy(send_buffer, "error");send(msgsock, send_buffer, strlen(send_buffer), 0);closesocket(msgsock);}}closesocket(sock);WSACleanup();return 0;
}

驱动层代码

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com
#include "LySocket.hpp"// 传输结构体
typedef struct
{int uuid;char username[256];char password[256];
}SocketData;// 验证账号密码是否正确
BOOLEAN CheckDriver()
{NTSTATUS status = STATUS_SUCCESS;HANDLE hTdiAddress = NULL;HANDLE hTdiEndPoint = NULL;PDEVICE_OBJECT pTdiAddressDevObj = NULL;PFILE_OBJECT pTdiEndPointFileObject = NULL;LONG pServerIp[4] = { 127, 0, 0, 1 };LONG lServerPort = 8888;// TDI初始化status = TdiOpen(&pTdiAddressDevObj, &pTdiEndPointFileObject, &hTdiAddress, &hTdiEndPoint);if (!NT_SUCCESS(status)){return STATUS_SUCCESS;}// TDI TCP连接服务器status = TdiConnection(pTdiAddressDevObj, pTdiEndPointFileObject, pServerIp, lServerPort);if (!NT_SUCCESS(status)){return STATUS_SUCCESS;}SocketData ptr;RtlZeroMemory(&ptr, sizeof(SocketData));// 填充结构ptr.uuid = 1001;RtlCopyMemory(ptr.username, "lyshark", strlen("xxxxxxx"));RtlCopyMemory(ptr.password, "123123", strlen("xxxxxx"));// TDI TCP发送信息status = TdiSend(pTdiAddressDevObj, pTdiEndPointFileObject, &ptr, sizeof(SocketData));if (!NT_SUCCESS(status)){return STATUS_SUCCESS;}// 创建接收信息多线程, 循环接收信息char szRecvData[8192] = { 0 };ULONG ulRecvDataLenngth = 8192;RtlZeroMemory(szRecvData, ulRecvDataLenngth);// TDI TCP接收信息do{ulRecvDataLenngth = TdiRecv(pTdiAddressDevObj, pTdiEndPointFileObject, szRecvData, ulRecvDataLenngth);if (0 < ulRecvDataLenngth){DbgPrint("接收数据: %s\n", szRecvData);if (strncmp(szRecvData, "success", 7) == 0){// 释放TdiClose(pTdiEndPointFileObject, hTdiAddress, hTdiEndPoint);return TRUE;}else if (strncmp(szRecvData, "error", 5) == 0){// 释放TdiClose(pTdiEndPointFileObject, hTdiAddress, hTdiEndPoint);return FALSE;}break;;}} while (TRUE);// 释放TdiClose(pTdiEndPointFileObject, hTdiAddress, hTdiEndPoint);return STATUS_SUCCESS;
}VOID UnDriver(PDRIVER_OBJECT driver)
{DbgPrint("驱动卸载成功 \n");
}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{DbgPrint("hello lyshark.com \n");BOOLEAN ref = CheckDriver();if (ref == FALSE){DbgPrint("[LyShark.com] 驱动已过期,无法加载 \n");Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;}DbgPrint("[*] 驱动正常使用 \n");Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;
}

运行应用层服务端,并运行驱动程序,则会验证该驱动是否合法,如果合法则加载不合法则拒绝;

这篇关于驱动开发:内核封装TDI网络通信接口的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/714130

相关文章

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

SpringBoot中封装Cors自动配置方式

《SpringBoot中封装Cors自动配置方式》:本文主要介绍SpringBoot中封装Cors自动配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot封装Cors自动配置背景实现步骤1. 创建 GlobalCorsProperties

新特性抢先看! Ubuntu 25.04 Beta 发布:Linux 6.14 内核

《新特性抢先看!Ubuntu25.04Beta发布:Linux6.14内核》Canonical公司近日发布了Ubuntu25.04Beta版,这一版本被赋予了一个活泼的代号——“Plu... Canonical 昨日(3 月 27 日)放出了 Beta 版 Ubuntu 25.04 系统镜像,代号“Pluc

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用