驱动开发:内核封装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

相关文章

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

基于Java开发一个极简版敏感词检测工具

《基于Java开发一个极简版敏感词检测工具》这篇文章主要为大家详细介绍了如何基于Java开发一个极简版敏感词检测工具,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录你是否还在为敏感词检测头疼一、极简版Java敏感词检测工具的3大核心优势1.1 优势1:DFA算法驱动,效率提升10

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块

Python用Flask封装API及调用详解

《Python用Flask封装API及调用详解》本文介绍Flask的优势(轻量、灵活、易扩展),对比GET/POST表单/JSON请求方式,涵盖错误处理、开发建议及生产环境部署注意事项... 目录一、Flask的优势一、基础设置二、GET请求方式服务端代码客户端调用三、POST表单方式服务端代码客户端调用四

Go语言网络故障诊断与调试技巧

《Go语言网络故障诊断与调试技巧》在分布式系统和微服务架构的浪潮中,网络编程成为系统性能和可靠性的核心支柱,从高并发的API服务到实时通信应用,网络的稳定性直接影响用户体验,本文面向熟悉Go基本语法和... 目录1. 引言2. Go 语言网络编程的优势与特色2.1 简洁高效的标准库2.2 强大的并发模型2.

Java 与 LibreOffice 集成开发指南(环境搭建及代码示例)

《Java与LibreOffice集成开发指南(环境搭建及代码示例)》本文介绍Java与LibreOffice的集成方法,涵盖环境配置、API调用、文档转换、UNO桥接及REST接口等技术,提供... 目录1. 引言2. 环境搭建2.1 安装 LibreOffice2.2 配置 Java 开发环境2.3 配