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

相关文章

VSCode开发中有哪些好用的插件和快捷键

《VSCode开发中有哪些好用的插件和快捷键》作为全球最受欢迎的编程工具,VSCode的快捷键体系是提升开发效率的核心密码,:本文主要介绍VSCode开发中有哪些好用的插件和快捷键的相关资料,文中... 目录前言1、vscode插件1.1 Live-server1.2 Auto Rename Tag1.3

Agent开发核心技术解析以及现代Agent架构设计

《Agent开发核心技术解析以及现代Agent架构设计》在人工智能领域,Agent并非一个全新的概念,但在大模型时代,它被赋予了全新的生命力,简单来说,Agent是一个能够自主感知环境、理解任务、制定... 目录一、回归本源:到底什么是Agent?二、核心链路拆解:Agent的"大脑"与"四肢"1. 规划模

Linux内核定时器使用及说明

《Linux内核定时器使用及说明》文章详细介绍了Linux内核定时器的特性、核心数据结构、时间相关转换函数以及操作API,通过示例展示了如何编写和使用定时器,包括按键消抖的应用... 目录1.linux内核定时器特征2.Linux内核定时器核心数据结构3.Linux内核时间相关转换函数4.Linux内核定时

Android使用java实现网络连通性检查详解

《Android使用java实现网络连通性检查详解》这篇文章主要为大家详细介绍了Android使用java实现网络连通性检查的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录NetCheck.Java(可直接拷贝)使用示例(Activity/Fragment 内)权限要求

Python+wxPython开发一个文件属性比对工具

《Python+wxPython开发一个文件属性比对工具》在日常的文件管理工作中,我们经常会遇到同一个文件存在多个版本,或者需要验证备份文件与源文件是否一致,下面我们就来看看如何使用wxPython模... 目录引言项目背景与需求应用场景核心需求运行结果技术选型程序设计界面布局核心功能模块关键代码解析文件大

C++多线程开发环境配置方法

《C++多线程开发环境配置方法》文章详细介绍了如何在Windows上安装MinGW-w64和VSCode,并配置环境变量和编译任务,使用VSCode创建一个C++多线程测试项目,并通过配置tasks.... 目录下载安装 MinGW-w64下载安装VS code创建测试项目配置编译任务创建 tasks.js

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二

Python实现简单封装网络请求的示例详解

《Python实现简单封装网络请求的示例详解》这篇文章主要为大家详细介绍了Python实现简单封装网络请求的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录安装依赖核心功能说明1. 类与方法概览2.NetHelper类初始化参数3.ApiResponse类属性与方法使用实