NDIS网络数据监控程序NDISMonitor(2)-----驱动与应用的中间层NdisHook
本工程是驱动vpcknt的一个封闭层而已,比较简单。
一、导出的API接口分析
1、Start
(1)加载驱动vpcknt.sys。
vpcknt.sys是从工程的资源文件中通过CreateDriverFileFromAppResources加载的。(所以启动NDIS时金山杀毒软件会警告)
得到驱动文件后调用StartVersionedDeviceDriver把驱动.sys加载。 (加载过程中还通过驱动读取了版本)
(驱动加载方法通过服务的方式,与前面文章<<虚拟桌面:一个简单的桌面管理工具>>是一样的)
(2)初始化PINITIALIZE_HOOK_INPUT的两个变量pihiHookInput 、pihoHookOutput;
且通过调用驱动的IOCTL_VPCKNT_INITIALIZE_HOOK初始化pihoHookOutput数据和PNT_PROTOCOL_LIST指针(即协议列表);
2、Stop
卸载驱动
3、Listen
OALIST_ITEM类型的数据指针作为入参数,驱动IO码为IOCTL_VPCKNT_SUBMIT_OALIST的调用,目的是提交OALIST数据。
4、WaitForPacket
这里先去判断上一个包状态中的bArePacketsRemaining标志,如果它为TRUE,表还有数据,那么直接去读;
否则调用WaitForMultipleObjects等待内核事件;
- HANDLE vhHandles[] = { g_hKernelEvent, g_hExitFromThread };
- DWORD dwWaitRes = g_hsPrevStats.bArePacketsRemaining ? WAIT_OBJECT_0 :
- ::WaitForMultipleObjects( 2, vhHandles, FALSE, INFINITE );
获得包和数据包的状态
- DWORD dwBytesReturned = 0;
- BOOL bIoctlRes = ::DeviceIoControl( g_hDevice, IOCTL_VPCKNT_GET_NEXT_PACKET,
- NULL, 0,
- g_pbStorage, MACRO_STORAGE_BUFFER_SIZE,
- & dwBytesReturned, NULL );
- if ( bIoctlRes != FALSE && dwBytesReturned != 0 )
- {
- // allocate the packet memory.
- BYTE* pb = (BYTE*) ::malloc( dwBytesReturned );
- if ( pb == NULL )
- return FALSE;
- else
- ::memcpy( pb, g_pbStorage, dwBytesReturned );
- // return.
- g_hsPrevStats = * (HOOK_STATS*) pb;
- if ( psStats )
- * psStats = * (HOOK_STATS*) pb;
- * pppPacketPtr = (PNEXT_PACKET) ( pb + sizeof( HOOK_STATS ) );
二、总结:
1、原子操作
通过原子操作能保证在多线程时保证得调用完Start,才能使用Listen和Stop,起到的作用与关键代码类似。
(1)在Start开始时:
EHS_INITIALIZING为1;
EHS_NOT_INITIALIZED为0;
- LONG prev = ::InterlockedCompareExchange( & g_lHooked, EHS_INITIALIZING, EHS_NOT_INITIALIZED );
- if ( prev != EHS_NOT_INITIALIZED )
- return FALSE;
g_lHooked最开始为0,上面的代码后g_lHooked为 1 ;
(2)在Start结束时:
- g_lHooked = EHS_FUNCTIONING;
EHS_FUNCTIONING为 2 ;
(3)在Stop里:
EHS_FUNCTIONING 为 2;
EHS_STOPPING 为 3 ;
- LONG prev = ::InterlockedCompareExchange( & g_lHooked, EHS_STOPPING, EHS_FUNCTIONING );
- if ( prev != EHS_FUNCTIONING )
- return;
因为经过了Start 的结束后g_lHooked为 2 ; 所以经过上面的代码后g_lHooked 为 3 ;
1、InterlockedCompareExchange
InterlockedCompareExchange属于Interlocked系列互锁函数之一,常用于多线程编程。
类似的还有下面的几个:
//增减
(1) LONG InterlockedIncrement(IN OUT LONG volatile *lpAddend);
lpAddend为长整型变量的地址,返回值为原始值。这个函数的主要作用是原子性自增(相当于++操作)。
(2) LONG InterlockedDecrement(IN OUT LONG volatile *lpAddend);
lpAddend为长整型变量的地址,返回值为原始值。这个函数的主要作用是原子性自减(相当于--操作)。
(3) LONG InterlockedExchangeAdd ( LPLONG Addend, LONG Increment );
Addend为长整型变量的地址,Increment为想要在Addend指向的长整型变量上增加的数值(可以是负数)。这个函数的主要作用是保证这个加操作为一个原子访问。
//交换
(4) LONG InterlockedExchange( LPLONG Target, LONG Value );
用第二个参数的值取代第一个参数指向的值。函数返回值为原始值。
(5) PVOID InterlockedExchangePointer( PVOID *Target, PVOID Value );
用第二个参数的值取代第一个参数指向的值。函数返回值为原始值。
//比较交换
(6) LONG InterlockedCompareExchange( LPLONG Destination, LONG Exchange, LONG Comperand );
如果第三个参数与第一个参数指向的值相同,那么用第二个参数取代第一个参数指向的值。函数返回值为原始值。
(7) PVOID InterlockedCompareExchangePointer ( PVOID *Destination, PVOID Exchange, PVOID Comperand );
如果第三个参数与第一个参数指向的值相同,那么用第二个参数取代第一个参数指向的值。函数返回值为原始值。
NDIS网络数据监控程序NDISMonitor(2)-----驱动与应用的中间层NdisHook相关推荐
- 网络数据包拦截通用技术(协议驱动hook)
网络数据包拦截通用技术 作者:甘嘉平 (gjp) 看到很多仁兄提供的数据包的拦截技术,其中最多的是编写IM DRIVER在NDIS中间层 对MINIPORT(网卡驱动程序)和协议驱动程序之间的数据包进 ...
- Linux内核网络数据发送(六)——网络设备驱动
Linux内核网络数据发送(六)--网络设备驱动 1. 前言 2. 驱动回调函数注册 3. `ndo_start_xmit` 发送数据 4. `igb_tx_map` 1. 前言 本文主要介绍设备通过 ...
- NDIS网络驱动程序-----
from:http://blog.sina.com.cn/s/blog_61d65e360100waop.html NDIS网络驱动程序-----学习(一) (2011-08-15 21:48:14) ...
- 网络数据包拦截通用技术
网络数据包拦截通用技术 作者:甘嘉平 (gjp) 看到很多仁兄提供的数据包的拦截技术,其中最多的是编写IM DRIVER在NDIS中间层 对MINIPORT(网卡驱动程序)和协议驱动程序之间的数据包进 ...
- COPY FROM 文章标题 网络数据包拦截通用技术
COPY FROM 文章标题 网络数据包拦截通用技术 看到很多仁兄提供的数据包的拦截技术,其中最多的是编写IM DRIVER在NDIS中间层 对MINIPORT(网卡驱动程序)和协议驱动程序之间的数据 ...
- 《数据科学:R语言实现》——2.7 爬取网络数据
本节书摘来自华章计算机<数据科学:R语言实现>一书中的第2章,第2.7节,作者 丘祐玮(David Chiu),更多章节内容可以访问云栖社区"华章计算机"公众号查看. ...
- linux receive函数,Linux网络 - 数据包的接收过程
的方式写入到指定的内存地址,该地址由网卡驱动分配并初始化.注: 老的网卡可能不支持DMA,不过新的网卡一般都支持. 3: 网卡通过硬件中断(IRQ)通知CPU,告诉它有数据来了 4: CPU根据中断表 ...
- 网络数据包收发流程(三):e1000网卡和DMA
早就想整理网络数据包收发流程了,一直太懒没动笔.今天下决心写了 一.硬件环境 intel82546:PHY与MAC集成在一起的PCI网卡芯片,很强大 bcm5461: PHY芯片,与之对应的MAC ...
- Linux内核网络数据发送(五)——排队规则
Linux内核网络数据发送(五)--排队规则 1. 前言 2. `qdisc_run_begin()` and `qdisc_run_end()`:仅设置 qdisc 状态位 3. `__qdisc_ ...
最新文章
- 菜鸟学习Spring——60s利用JoinPoint获取參数的值和方法名称
- java sqlite mybatis_Spring boot + Mybatis + SQLite 搭建blog API
- fat32 linux 打包工具_一个方便的用于创建树莓派 SD 卡镜像的程序 | Linux 中国
- C++多线程基础笔记
- 快讯:阿里巴巴加入JCP执行委员会
- 3140: [Hnoi2013]消毒
- geoserver三维_集团公司自主研发三维GIS平台产品——GeniusWorld 2.0 C版本发布
- php 环信easyui_环信easeui集成:坑总结2018
- 剑指offer面试题32 - III. 从上到下打印二叉树 III(二叉树)(BFS)
- 2017百度之星初赛:A-1001. 小C的倍数问题
- Java 登录拦截器
- 网易云Android高级,网易云音乐Android新版 一键升本地音质
- 羊年祝福语(羊年祝福大全)
- 【离散数学】一阶/谓词逻辑思维导图
- vscode 经常弹出:尝试在目标目录创建文件时发生一个错误 重试 跳过这个文件 关闭安装程序
- 2022-2027年中国肺炎疫苗行业市场运行现状及投资战略研究报告
- java文件读取报(文件名、目录名或卷标语法不正确。)
- 黑马程序员_Java_异常
- 包载信使mRNA的多西环素纳米脂质体|雷公藤红素纳米脂质体RNA核糖核酸(实验原理)
- 5G行业专网赋能!《5G垂直行业专网设计及部署白皮书》正式发布!
热门文章
- php+mysql 员工管理系统 学生课设源码
- 测量block size 为8K ,自动分配的本地管理表空间的位图block一位能管理多少空间
- Resource	Path	Location	Type Project configuration is not up-to-date with pom.xml. Run Ma
- Java之数组的定义格式,【默认值规则】,Java内存划分5大区,面向对象类的基本定义和对象的使用,private和this关键字,类的构造方法,标准类的组成部分。
- 亚阈值区MOSFET阈值电压Vth随温度变化曲线仿真【Cadence】
- SLAM数学篇:问题表述
- 15_细菌的繁殖与扩散
- 毕节计算机考试准考证打印,2016年9月毕节计算机三级四级准考证打印入口,计算机等级考试时间查询...
- Aruba7010 默认密码_【对讲机的那点事】如何为您的数字对讲机热点配置安全密码...
- Ansys Speos | 联合 optiSLang 背光板设计优化方案