当前位置: 首页 > news >正文

windows 驱动实例分析系列: NDIS 6.0的Filter 驱动改造(四)

 

驱动的测试代码解读

1. 打开设备对象:

// 1. 打开底层设备对象HANDLE hDevice = CreateFile(L"\\\\.\\NDISFilter", // 设备名称GENERIC_READ | GENERIC_WRITE, // 访问权限0, // 不共享NULL, // 默认安全属性OPEN_EXISTING, // 打开现有设备0, // 无特殊标志NULL // 无模板句柄);if (hDevice == INVALID_HANDLE_VALUE){std::cerr << "Failed to open NDISFilter device. Error: " << GetLastError() << std::endl;return 1;}

2. 获取网卡地址:

// 2. 获取网卡数目ULONG ulNetAdapterCount = 0;DWORD dwReadSize = 0;BOOL  nRet = FALSE;CHAR* pData = NULL;CHAR Temp[4];nRet = DeviceIoControl(hDevice,IOCTL_FILTER_GET_NUMBER,NULL,0,&ulNetAdapterCount,sizeof(ULONG),&dwReadSize,NULL);if (!nRet){std::cerr << "IOCTL_FILTER_GET_NUMBER DeviceIoControl Faild !" << std::endl;goto Exit;}// 3. 获取网卡的Mac地址pData = new CHAR[_BUFFER_SIZE];nRet = DeviceIoControl(hDevice,IOCTL_FILTER_GET_ALL_ADDRESS,NULL,0,pData,ulNetAdapterCount * _MAC_LENGTH,&dwReadSize,NULL);if (!nRet){std::cerr << "IOCTL_FILTER_GET_ALL_ADDRESS DeviceIoControl Faild !" << std::endl;goto Exit;}for (int i = 0; i < ulNetAdapterCount; i++){UCHAR* pAddr = (UCHAR*)pData + i * _MAC_LENGTH;std::cout << i << ":" << std::hex << *(pAddr + 0) << std::hex << *(pAddr + 1) << std::hex << *(pAddr + 2) << std::hex << *(pAddr + 3) << std::hex << *(pAddr + 4) << std::hex << *(pAddr + 5) << std::endl;}

3. 发送数据包

        // 4. 测试发送ICMP数据包PACKET_INFO PacketInfo;memset(&PacketInfo, 0, sizeof(PACKET_INFO));PacketInfo.SrcMac[0] = 0x00;PacketInfo.SrcMac[1] = 0x0C;PacketInfo.SrcMac[2] = 0x29;PacketInfo.SrcMac[3] = 0xDB;PacketInfo.SrcMac[4] = 0x9F;PacketInfo.SrcMac[5] = 0x34;PacketInfo.DesMac[0] = 0x00;PacketInfo.DesMac[1] = 0x0C;PacketInfo.DesMac[2] = 0x29;PacketInfo.DesMac[3] = 0xDB;PacketInfo.DesMac[4] = 0x9F;PacketInfo.DesMac[5] = 0x34;// 12.17.10.8PacketInfo.SrcIPv4 = inet_addr("12.17.10.8");PacketInfo.DesIPv4 = inet_addr("12.17.10.8");memset(PacketInfo.Data, 8, _DATA_SIZE);PacketInfo.Length = ICMP_PACKET_SIZE;// 发送数据包nRet = DeviceIoControl(hDevice,IOCTL_FILTER_SEND_DATA,&PacketInfo,sizeof(PACKET_INFO),&PacketInfo,sizeof(PACKET_INFO),&dwReadSize,NULL);if (!nRet){std::cerr << "IOCTL_FILTER_SEND_DATA DeviceIoControl Faild !" << std::endl;goto Exit;}std::cerr << "IOCTL_FILTER_SEND_DATA DeviceIoControl OK ! count = " << nCount << std::endl;// 5. 获取数据包nRet = DeviceIoControl(hDevice,IOCTL_FILTER_RECEIVE_DATA,&PacketInfo,sizeof(PACKET_INFO),&PacketInfo,sizeof(PACKET_INFO),&dwReadSize,NULL);if (!nRet){std::cerr << "IOCTL_FILTER_RECEIVE_DATA DeviceIoControl Faild !" << std::endl;goto Exit;}std::cerr << "IOCTL_FILTER_RECEIVE_DATA DeviceIoControl OK ! count = " << nCount++<< ", dwReadSize = " << dwReadSize << ", struct->length = " << PacketInfo.Length << std::endl;

4. 打印数据包:

        try{memset(pData, 0, _BUFFER_SIZE);PCHAR pCopy = pData;for (int i = 0; i < dwReadSize; i++){memset(Temp, 0, 4);int n = _itoa_s((UCHAR)PacketInfo.Data[i], Temp, 16);Temp[strlen(Temp)] = '\0';strcpy_s(pCopy, 4, Temp);pCopy += strlen(Temp);}std::cerr << "IOCTL_FILTER_RECEIVE_DATA DeviceIoControl OK ! Data = " << pData << std::endl;}catch (const std::exception& ex){std::cerr << ex.what();}

5. 关闭设备 

Exit:if (NULL != pData) delete[]pData;std::cerr << " close NDISFilter device. OK!" << std::endl;// 关闭设备对象CloseHandle(hDevice);

代码在资源中的FilterDemo中。 

驱动的安装和测试

NDIS比较特殊,我们需要以下面的方式进行安装:

1. 打开任意一个网络适配器,定位到属性:

932fe3abe7dd4a2da129a50309109e24.png

2. 点击安装后,会有以下界面:

 5dda78da0c1f426e8d7ff5c47182b8b8.png

协议驱动也在这里安装,Filter选择服务就行。

3. 找到安装驱动的路径:

b212ec9edf71428fbefd28df6e50d89d.png 

4. 然后安装即可,中间会提示我们是否需要加载测试签名的驱动,选择是就好。 

5. 测试程序运行界面如下:

b8a154e13572407d935ff2b64384f7df.png

此时,我们注意到我们接收到的数据就是我们发送出去的数据,因为我们将缓冲区全部设置为8。 


http://www.mrgr.cn/news/61569.html

相关文章:

  • 在pgsql中any和in的区别
  • Oracle 第12章:包与集合
  • 内容营销专家刘鑫炜:AI搜索的查询结果都来自哪里?
  • 阻塞队列/生产者消费者问题
  • 【算法】Kruskal最小生成树算法
  • Linux云计算 |【第五阶段】CLOUD-DAY4
  • Java | Leetcode Java题解之第520题检测大写字母
  • Linux(一)
  • 从0开始搭建一个生产级SpringBoot2.0.X项目(五)使用 validation 验证参数
  • C++核心编程和桌面应用开发 第十七天(set和multiset容器 pair map和multimap容器)
  • Json库和文件操作
  • Cargo 的工作机制
  • 一道巧妙的卡特兰数建模
  • 聊聊解构的那些事
  • 本篇文章来介绍下dockerfile
  • LeetCode 热题 100 回顾2
  • Golang | Leetcode Golang题解之第519题随机翻转矩阵
  • 速盾:海外高防CDN有哪些优势?
  • SpringBoot篇(自动装配原理)
  • 〈壮志凌云:独行侠〉中的超高音速战机
  • Android Studio 无法查看Kotlin源码的解决办法
  • 了解一下,RN中怎么加载 threejs的
  • openEuler 系统中单引号、双引号及转义字符的应用
  • Topaz Video AI for Mac 视频无损放大软件安装教程【保姆级,操作简单轻松上手】
  • 如何解决 Ansys Electronics Desktop 中的 HPC Pack 许可错误
  • C++引用的属性