NDIS网络数据监控程序NDISMonitor(2)-----驱动与应用的中间层NdisHook_Jackchenyj的博客-程序员宅基地

技术标签: window xp 驱动(USB)/FireFox插件/汇编  网络编程/协议  

转载请标明是引用于 http://blog.csdn.net/chenyujing1234 

欢迎大家拍砖!

 

本工程是驱动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 );

  如果第三个参数与第一个参数指向的值相同,那么用第二个参数取代第一个参数指向的值。函数返回值为原始值。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chenyujing1234/article/details/7819329

智能推荐

一道柯里化面试题_weixin_34082854的博客-程序员宅基地

这是一道朋友在群里发的一道题,我之前不是很懂柯里化,就自己试着写了一下,不知道算不算柯里化,望指教~下面是题目: function curry() { // your code..... } ================================ //写好之后一下代码可以正常运行...

洛谷2048 BZOJ2006 NOI2010 超级钢琴 线段树 堆 贪心_forever_shi的博客-程序员宅基地

题目链接题意:给你一个长度为nnn的序列,一个区间的权值是区间内的权值和,你要选择kkk个不相同长度在[l,r][l,r][l,r]的区间,使得这kkk个区间总权值和最大。n,k&amp;lt;=5e5n,k&amp;lt;=5e5n,k&lt;=5e5。题解:算是送我退役的题吧。如果一轮省选之前我做了这个题,可能结果就会不一样了吧,可惜没有如果。显然是找长度在[l,r][l,r][l,...

关于游戏陪玩系统源码后台管理系统前端项目的思考_云豹科技程序猿的博客-程序员宅基地_vue游戏管理系统

开发游戏陪玩系统源码后台管理系统是大部分游戏陪玩系统源码前端开发人员接触过的项目,如何更好的进行项目的搭建、组件的开发、数据结构的设计等等,这些都是需要考虑的问题。以下是我结合一些项目的经历和其他大佬的项目代码与技术分享,做出了对于后台管理系统中前端项目的思考。1. 了解需求,熟悉掌握需求这一要求无论是对于游戏陪玩系统源码前端开发人员或是其他端的开发人员,都是能够顺利开发项目的前提。在开发游戏陪玩系统源码之前,需对 PM 的需求了然于胸,对原型设计能够充分掌握。理解每一个操作逻辑的含义,并且扩散思维思考

OBEX(一)_sui1005316018的博客-程序员宅基地

一、概述1、OBEX v2.0(v2.0版本开始OBEX直接在L2CAP上传输,v2.0版本以前OBEX在RFCOMM上传输)2、OBEX即Object Exchange Protocol,对象交换协议3、OBEX协议是典型的client/server request-response模型4、OBEX v2.0蓝牙协议层次结构图:5、OBEX可以用来传输vCard(电话本),vCalendar(电子日历),vMessage(短信和email)和vNotes(电子笔记)。二、OBE

K3CLOUD替代方案_weixin_30294021的博客-程序员宅基地

路径【生产制造】-&gt;【工程数据】-&gt;【替代方案】-&gt;【替代方案】应用场景实际业务处理中,由于订单取消、工程变更、客户需求变化、预测或计划不准确等原因造成原材料库存积压、呆滞,使企业在仓库积压大量资金。企业出于降低库存成本、减低物料成本、或及时响应客户需求等因素考虑,都会存在使用替代物料的情况。物料替代的处理涉及工程、销售、生产计划、物料需求计划、生产、仓库、采...

Freemarker实例教程_sujiacheng_123的博客-程序员宅基地

转载:http://blog.csdn.net/chenghui0317/article/details/7832474一、Freemarker的介绍    Freemarker 是一款模板引擎,是一种基于模版生成静态文件的通用 工具,它是为Java程序员提供的一个开发包,或者说是一个类库,它不是面向最终用户的,而是为程序员提供了一款可以嵌入他们开发产品的应用程序。  

随便推点

jpa一对多OneToMany关联查询;debug下lazy失效原因_好大的月亮的博客-程序员宅基地_jpa onetomany查询

jpa一对多实体类关联查询package com.xx.xx.settings.domain;import lombok.*;import lombok.experimental.Accessors;import javax.persistence.*;import java.io.Serializable;import java.util.ArrayList;import java.util.Date;import java.util.List;@Table(name = "con

DDOS小记_Amire0x的博客-程序员宅基地

DDOS小记分类以攻击方向来区分的话网络基于大量的Flood耗尽目标网络带宽资源Syn Flood,发送大量伪造的 TCP 连接请求,从而使得被攻击方资源耗尽(CPU 满负载或内存不足)的攻击方式 。 用户向服务器发送报文后突然死机或掉线,那么服务器在发出应答报文后就无法收到客户端的确认报文(第三次握手无法完成),这时服务器端一般会重试并等待一段时间(至少 30s)后再丢弃这个未完成的连接ICMP Flood,Connection Flood利用真实的 IP 地址向服务

YV12转Iplimage_qq76211822的博客-程序员宅基地

void HC_Out(char *pBuf, DWORD dwWidth, DWORD dwHeight){ if(!pBuf){ return; } IplImage* pImage_YV12 = cvCreateImageHeader(cvSize(dwWidth, dwHeight / 2 * 3), IPL_DEPTH_8U, 1); if (!pImage_YV12){

100行JS实现HTML5的3D贪吃蛇游戏_图扑软件的博客-程序员宅基地

js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型,多次想尝试提交个小游戏但总无法写出让自己满意还能控制在这么小的字节范围。自己写不出来,站在巨人肩膀总是有机会吧,想起《基于HTML5的电信网管3D机房监控应用》这篇提到的threejs,babyl

NotePad++ 作者怎么会这么坏_minky糕的博客-程序员宅基地_notepad++作者

唉,好好的notepad++,被弄得乌烟瘴气,虽然技术无国界,但还是恶心到了

docker容器重启_小卤蛋本蛋的博客-程序员宅基地_重启docker容器

1.先查看有哪些容器docker ps -a2.假如容器名称是nginx,停止容器nginxdocker stop nginx3.启动容器nginxdocker start nginx4.如果是docker服务出了问题,重启docker服务systemctl restart docker

推荐文章

热门文章

相关标签